admin管理员组文章数量:1416302
DISCLAIMER: i'm new at React, and just trying to build good habits.
So, the example would be a simple contacts app, where you type in names, and all the names are rendered below the input field. pic.1 simple contacts app mechanics
First, and the most intuitive way, of making this work is using useState()
hook with our input field. It's also widely suggested in tutorials around the web.
method 1 with useState()
:
const [inputState, setInputState] = useState('');
const [people, setPeople] = useState([]);
const onChange = (event) => {
setInputState(event.target.value)
}
const onSubmit = (e) => {
e.preventDefault()
setPeople([...people, inputState])
setInputState('') // pay extra attention to this line
}
// ...
<form onSubmit={onSubmit}>
<input onChange={onChange} value={inputState} />
</form>
//...
Looks simple enough. We have inputState
, that is up-to-date with input field because of onChange
function. However (!!!), in this video about mon react-hook mistakes, Kyle points, that this method isn't the optimal one, cause it makes the whole page re-render every time we change input value. So, he suggests using useRef()
hook instead.
*method 2 with useRef()
:*
const [people, setPeople] = useState([]);
const inputRef = useRef([]);
const onSubmit = (e) => {
e.preventDefault()
setPeople([...people, inputRef.current.value])
// inputRef.current.value = '' <== won't work
}
// ...
<form onSubmit={onSubmit}>
<input ref={inputRef} />
</form>
//...
The second method works fine, and re-renders the page only once, when the submit event happens. However, we are going to submit this form multiple times, so we want onSubmit
function to clear the input value. If we try adding inputRef.current.value = '';
in the end of onSubmit
function, it breaks our app. The reason must be that setting state is asynchronous, so it ends up with updating state after making input value empty. To resolve it we can use another hook, useEffect()
, which will clear our input value only after our stateful element is updated
method 2 updated with useEffect()
:
const [people, setPeople] = useState([]);
const inputRef = useRef([]);
useEffect(() => inputRef.current.value = '', [people])
const onSubmit = (e) => {
e.preventDefault()
setPeople([...people, inputRef.current.value])
}
// ...
<form onSubmit={onSubmit}>
<input ref={inputRef} />
</form>
//...
Finally. What's the question??
We have these two methods:
First one is intuitive, using simple mechanics, using just one hook, BUT re-rendering the page multiple times.
Second one uses as much as three different hooks, more plex mechanics, BUT re-renders only on submit.
Which should I use? Which could be considered the correct one? Or maybe I'm missing something and the answer is 'neither'?
Some similar questions here discuss the differences, but as we are already aware of differences, what to choose?
If your form doesn't have validation, you can use
useRef
.
But should I? Does this stack of hooks really improve the performance?
I'd appreciate your thoughts and suggestions!
DISCLAIMER: i'm new at React, and just trying to build good habits.
So, the example would be a simple contacts app, where you type in names, and all the names are rendered below the input field. pic.1 simple contacts app mechanics
First, and the most intuitive way, of making this work is using useState()
hook with our input field. It's also widely suggested in tutorials around the web.
method 1 with useState()
:
const [inputState, setInputState] = useState('');
const [people, setPeople] = useState([]);
const onChange = (event) => {
setInputState(event.target.value)
}
const onSubmit = (e) => {
e.preventDefault()
setPeople([...people, inputState])
setInputState('') // pay extra attention to this line
}
// ...
<form onSubmit={onSubmit}>
<input onChange={onChange} value={inputState} />
</form>
//...
Looks simple enough. We have inputState
, that is up-to-date with input field because of onChange
function. However (!!!), in this video about mon react-hook mistakes, Kyle points, that this method isn't the optimal one, cause it makes the whole page re-render every time we change input value. So, he suggests using useRef()
hook instead.
*method 2 with useRef()
:*
const [people, setPeople] = useState([]);
const inputRef = useRef([]);
const onSubmit = (e) => {
e.preventDefault()
setPeople([...people, inputRef.current.value])
// inputRef.current.value = '' <== won't work
}
// ...
<form onSubmit={onSubmit}>
<input ref={inputRef} />
</form>
//...
The second method works fine, and re-renders the page only once, when the submit event happens. However, we are going to submit this form multiple times, so we want onSubmit
function to clear the input value. If we try adding inputRef.current.value = '';
in the end of onSubmit
function, it breaks our app. The reason must be that setting state is asynchronous, so it ends up with updating state after making input value empty. To resolve it we can use another hook, useEffect()
, which will clear our input value only after our stateful element is updated
method 2 updated with useEffect()
:
const [people, setPeople] = useState([]);
const inputRef = useRef([]);
useEffect(() => inputRef.current.value = '', [people])
const onSubmit = (e) => {
e.preventDefault()
setPeople([...people, inputRef.current.value])
}
// ...
<form onSubmit={onSubmit}>
<input ref={inputRef} />
</form>
//...
Finally. What's the question??
We have these two methods:
First one is intuitive, using simple mechanics, using just one hook, BUT re-rendering the page multiple times.
Second one uses as much as three different hooks, more plex mechanics, BUT re-renders only on submit.
Which should I use? Which could be considered the correct one? Or maybe I'm missing something and the answer is 'neither'?
Some similar questions here discuss the differences, but as we are already aware of differences, what to choose?
If your form doesn't have validation, you can use
useRef
.
But should I? Does this stack of hooks really improve the performance?
I'd appreciate your thoughts and suggestions! Share Improve this question asked Apr 23, 2023 at 17:01 Matvey SokolovskyMatvey Sokolovsky 431 silver badge5 bronze badges
2 Answers
Reset to default 5I haven't watched the video, but if the author suggests to use useRef()
instead of state to save performance, he doesn't seem to have much clue of how React actually works.
React only applies changes to the DOM when it spots the changes in the virtual DOM, which is the representation of the nodes used to keep track of necessary changes. If your state change causes many DOM updates, it means that you do it wrong, most likely recreate a state value unnecessarily. The easiest way to this mistake is to recreate object in state, instead of memoizing it.
Using states means achieving much cleaner and reusable React code. Use useRef()
only when you need to perform an action on a DOM element (like focus()
) or when you need a value that needs to be accessed in the same cycle and/or is not rendered.
We have had issues with performance on large forms (forms with lots of inputs) and using state. While a simple state update is not much of a performance hit, if there are fields that update depending on that state, there may be a large performance hit, as there was in our case.
Our solution was to move to react hook form
. While this may not answer your question directly, this is the direction we ended up going to solve issues that using state on the form caused and not to go down the slightly messy useRef
path.
You also get some great methods like isDirty
and isValid
to help in form submission. You can also clear the form relatively easy with the reset
method.
本文标签:
版权声明:本文标题:javascript - What is BETTER useState or useRef, when handling multiple form inputs in React? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744617880a2615842.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论