我开始使用react挂钩,并决定在useState函数中放置一个对象而不是变量:

const [foo, setFoo] = useState({
    term: '',
    loading: false,
    ...
});


但是后来我想更新它时

const onChange = (e) => {

    const { value } = e.target;

    setFoo({ ...foo, term: value });

    if(value) setFoo({ ...foo, loading: true });

    ...

}

...

return (
   ...
   <input onChange={onChange} value={term} />
   ...
)


1.为什么在第二个setFoo中,当我检查foo对象时,总是获得与term相等的''属性,就像初始值一样,并且输入内容没有使用键入的字符更新吗?

-当我删除第二个setFoo时,它可以工作,所以我想是因为setFoo是异步的,但如何解决此问题呢?

-我知道我们可以通过一次只调用setFoo来解决此问题,但是我想知道其他解决方案吗?

2.为什么这种问题在redux中从未发生过?

最佳答案

1.可能是因为您必须销毁foo而不是state

setFoo({ ...foo, term: value });


working useState example

2.查看其他挂钩,尤其是useReducer


  当您具有包含多个子值的复杂状态逻辑时,或者当下一个状态依赖于前一个值时,useReducer通常比useState更可取。


您的代码可以变成:

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

07-24 17:32