[英]Issues with successive state object setting in reactjs hooks
I am starting to using react hooks and i decide to put an object instead of a variable in the useState
function : 我开始使用react钩子,我决定在
useState
函数中放置一个对象而不是一个变量:
const [foo, setFoo] = useState({
term: '',
loading: false,
...
});
but later when I want to update it 但是后来我想更新它时
const onChange = (e) => {
const { value } = e.target;
setFoo({ ...foo, term: value });
if(value) setFoo({ ...foo, loading: true });
...
}
...
return (
...
<input onChange={onChange} value={term} />
...
)
1. Why in the second setFoo
when I check the foo
object I get alway term
property equal to ''
exactly like the initial value and the input don't get updated with the typed characters ? 1.为什么在第二个
setFoo
当我检查foo
对象时,总是获得等于''
term
属性,就像初始值一样,并且输入内容不会使用键入的字符进行更新?
- When I delete the second setFoo
it works so I guess because setFoo
is asynchronous but how to solve this issue ?. -当我删除第二个
setFoo
它可以工作,所以我想是因为setFoo
是异步的,但如何解决此问题呢?
- I know that we can workaround this issue by managing to call setFoo
just once but i want to know other solutions ? -我知道我们可以通过
setFoo
只调用一次setFoo
来解决此问题,但是我想知道其他解决方案吗?
2. Why this kinda of issues never happened in redux
? 2.为什么这类问题在
redux
从未发生过?
The solution: use one setFoo
like this: 解决方案:像这样使用一个
setFoo
:
const onChange = (e) => {
const { value } = e.target;
setFoo({ term: value, loading: !!value });
...
}
!!
means "convert to boolean value". 表示“转换为布尔值”。
You can solve the issue by calling setFoo
only once with all the new key-value pairs, like this: 您可以通过使用所有新的键值对仅调用一次
setFoo
来解决此问题,如下所示:
const onChange = (e) => {
const { value } = e.target;
const loading = value ? true : false;
setFoo({ ...state, term: value, loading });
....
}
Update: 更新:
For complex state update and more control on that part, you can use useReducer , and write a separate reducer to update the state. 对于复杂的状态更新和对该部分的更多控制,可以使用useReducer ,并编写一个单独的reducer来更新状态。
1. Probably because you have to destruct foo
instead of state
1.可能是因为您必须破坏
foo
而不是state
setFoo({ ...foo, term: value });
working useState
example 工作
useState
示例
2. Take a look at the additional hooks, especially useReducer 2.看一下额外的挂钩,尤其是useReducer
useReducer
is usually preferable touseState
when you have complex state logic that involves multiple sub-values or when the next state depends on the previous one.当您具有涉及多个子值的复杂状态逻辑时,或者当下一个状态取决于上一个状态时,
useReducer
通常比useState
更可取。
And your code can become: 您的代码可以变成:
const reducer = (state, action) {
switch(action.type) {
case 'loading':
return { ...state, loading: true };
case 'loaded':
default:
return { ...state, loading: false };
}
}
const initialState = {
term: '',
loading: false,
}
const [state, dispatch] = useReducer(reducer, initialState);
dispatch({
type: e.target.value ? 'loaded' : 'loading'
});
working useReducer
example on CodeSandbox useReducer
上的work useReducer
示例
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.