I found that there are several ways to handle user's text input with hooks. What is more preferable or proper way to handle an input with hooks? Which would you use?
1) The simplest hook to handle input, but more fields you have, more repetitive code you have to write.
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
events:
onChange={event => setPassword(event.target.value)}
onChange={event => setUsername(event.target.value)}
2) Similar to above example, but with dynamic key name
const [inputValues, setInputValues] = useState({
username: '', password: ''
});
const handleOnChange = event => {
const { name, value } = event.target;
setInputValues({ ...inputValues, [name]: value });
};
event:
onChange={handleOnChange}
3) An alternative to useState
, and as said on ReactJS docs, useReducer
is usually preferable to useState
.
const [inputValues, setInputValues] = useReducer(
(state, newState) => ({ ...state, ...newState }),
{username: '', password: ''}
);
const handleOnChange = event => {
const { name, value } = event.target;
setInputValues({ [name]: value });
};
event:
onChange={handleOnChange}
4) useCallback
will return a memoized version of the callback that only changes if one of the dependencies has changed.
const [inputValues, setInputValues] = useState({
username: '', password: ''
});
const handleOnChange = useCallback(event => {
const { name, value } = event.target;
setInputValues({ ...inputValues, [name]: value });
});
event:
onChange={handleOnChange}
How about writing a reusable function that returns the input value ... and the <input>
itself:
function useInput({ type /*...*/ }) {
const [value, setValue] = useState("");
const input = <input value={value} onChange={e => setValue(e.target.value)} type={type} />;
return [value, input];
}
That can then be used as:
const [username, userInput] = useInput({ type: "text" });
const [password, passwordInput] = useInput({ type: "text" });
return <>
{userInput} -> {username} <br />
{passwordInput} -> {password}
</>;