Trong React, thực sự không có nhiều cách để làm việc với Form. Nó không quá khác khi bạn tạo form với DOM APIs trong Javascript thông thường. Tôi nghĩ điều đó thật tuyệt vời.
Bạn có thể thêm event vào hàm onSubmit trên Form. Sau đó, nó sẽ liên kết với form của bạn và các element trong form để giúp bạn xử lí form hiệu quả hơn.
Bạn có một input và alert giá trị của nó khi submit form.
import*as React from'react'functionUsernameForm({onSubmitUsername}){return(<form><div><label>Username:</label><input type="text"/></div><button type="submit">Submit</button></form>)}functionApp(){constonSubmitUsername=username=>alert(`You entered: ${username}`)return<UsernameForm onSubmitUsername={onSubmitUsername}/>}exportdefault App
Có một số cách để lấy giá trị của một input trong form như sau:
- Thông qua index: event.target.elements[0].value
- Thông qua name hoặc id: event.target.elements.usernameInput.value
- Một số cách khác
Đáp án:
import * as React from 'react'
function UsernameForm({onSubmitUsername}) {
function handleSubmit(event) {
event.preventDefault()
onSubmitUsername(event.target.elements.usernameInput.value)
}
return (
<form onSubmit={handleSubmit}>
<div>
<label htmlFor="usernameInput">Username:</label>
<input id="usernameInput" type="text" />
</div>
<button type="submit">Submit</button>
</form>
)
}
function App() {
const onSubmitUsername = username => alert(`You entered: ${username}`)
return <UsernameForm onSubmitUsername={onSubmitUsername} />
}
export default App
Sử dụng refs
Một cách khác để lấy giá trị của input trong Form là sử dụng ref trong React. Ref là một object giữ một giá trị không đổi qua các lần re-render của component. Nó có current property để bạn lấy giá trị của ref.
Bạn hãy sử dụng ref để lấy giá trị của input trong bài tập 1 bằng ref.
Đáp án:
import*as React from'react'functionUsernameForm({onSubmitUsername}){const usernameInputRef = React.useRef()functionhandleSubmit(event){
event.preventDefault()onSubmitUsername(usernameInputRef.current.value)}return(<form onSubmit={handleSubmit}><div><label htmlFor="usernameInput">Username:</label><input id="usernameInput" type="text" ref={usernameInputRef}/></div><button type="submit">Submit</button></form>)}functionApp(){constonSubmitUsername=username=>alert(`You entered: ${username}`)return<UsernameForm onSubmitUsername={onSubmitUsername}/>}exportdefault App
Validate lower-case cho input
Với React, bạn có thể sử dụng một hook đặc biệt gọi là useState.Ví dụ đơn giản như sau:functionCounter(){const[count, setCount]= React.useState(0)constincrement=()=>setCount(count +1)return<button onClick={increment}>{count}</button>}
React.useState nhận vào giá trị mặc định và return về một array. Sau đó, bạn có thể descontruct cái array để lấy state và hàm updater của state đó. Tham khảo: https://reactjs.org/docs/hooks-state.html
Trong bài tập này, chúng ta giả sử rằng username input chỉ chấp nhận ký tự chữ thường(lower-case). Nếu người dùng gõ vào chữ hoa, bạn phải hiện error message.
Nếu bạn muốn form được dynamic thì bạn cần phải:
- Component state phải lưu giá trị đông(dynamic value)- ở đây là error message.
- Thêm một change handler vào input để chúng ta biết được giá trị mà người dùng đã thay đổi.
Bài tập này hơi khó một tí nên bạn có thể tham khảo một số bước sau nhe:
Tạo một function handleChange nhận event là tham số và sử dụng event.target.value để lấy giá trị của input. Nhớ rằng là event này chạy khi từ input, chứ không phải form
Sử dụng giá trị của input để xét xem có lỗi hay không. Lỗi xảy ra khi người dùng nhập giá trị chữ in hoa. Bạn có thể validate như sau: const isValid = value === value.loLowerCase()
Nếu có lỗi bạn set error state là: “Username must be lower case”.
Và cuối cùng là hiển thị lỗi lên một element.
Đáp án:
import*as React from'react'functionUsernameForm({onSubmitUsername}){const[error, setError]= React.useState(null)functionhandleSubmit(event){
event.preventDefault()onSubmitUsername(event.target.elements.usernameInput.value)}functionhandleChange(event){const{value}= event.target
const isLowerCase = value === value.toLowerCase()setError(isLowerCase ?null:'Username must be lower case')}return(<form onSubmit={handleSubmit}><div><label htmlFor="usernameInput">Username:</label><input id="usernameInput" type="text" onChange={handleChange}/></div><div role="alert" style={{color:'red'}}>{error}</div><button disabled={Boolean(error)} type="submit">
Submit
</button></form>)}functionApp(){constonSubmitUsername=username=>alert(`You entered: ${username}`)return(<div style={{minWidth:400}}><UsernameForm onSubmitUsername={onSubmitUsername}/></div>)}exportdefault App
Điều khiển giá trị của input
Thỉnh thoảng bạn sẽ cần control input của một trong một số trường hợp. Có thể bạn cần set giá trị của input khi người dùng click nút nào đó. Có thể bạn muốn thay đổi giá trị mà người dùng nhập vào.
Đó là lí do React hỗ trợ Controlled Form input. Hiện tại trong bài tập của chúng ta thì form là kiểu “uncontrolled” có nghĩa là trình duyệt đang giúp bạn quản lý giá trị của input và chúng ta sẽ được thông báo giá trị thay đổi thông qua những event như handleChange.
Nếu bạn cố ý muốn set lại giá trị cho input thì bạn có thể làm như sau: inputNode.value = ‘value’. Nhưng nó có vẻ hơi khó. Cho nên, React cho phép bạn set giá tri của input như sau:
<inputvalue={myInputValue}/>
Khi chúng ta làm điều này thì React sẽ đảm bảo rằng gia trị của input luôn là gia trị của biến myInputValue.
Bạn cần phải lưu giá trị của input username vào state(React.useState) và thêm onChange vào input để set lại giá trị cho input đó. Do ở đây, chúng ta có thể điều khiển giá trị của input nên chúng ta có thể chuyển về giá trị chữ thường bằng hàm toLowerCase() nên không bằng lưu error state nữa.
Bạn hãy thử dùng controlled form để viết lại form ở bài tập trên.
Đáp án:
import*as React from'react'functionUsernameForm({onSubmitUsername}){const[username, setUsername]= React.useState('')functionhandleSubmit(event){
event.preventDefault()onSubmitUsername(username)}functionhandleChange(event){setUsername(event.target.value.toLowerCase())}return(<form onSubmit={handleSubmit}><div><label htmlFor="usernameInput">Username:</label><input
id="usernameInput"
type="text"
onChange={handleChange}
value={username}/></div><button type="submit">Submit</button></form>)}functionApp(){constonSubmitUsername=username=>alert(`You entered: ${username}`)return(<div style={{minWidth:400}}><UsernameForm onSubmitUsername={onSubmitUsername}/></div>)}exportdefault App
Nguồn: viblo.asia