2

考虑在获取一些数据后我需要更新状态的代码,我只需要更新初始状态(clientData)的数据部分:

 const [clientData, setClientData] = useState({
    data: {},
    product: 'profile'
 });

 useEffect(() => {
    getProducts(1).then(res =>
      setClientData({ ...clientData, data: res.data })
    );
  }, []);

我怎样才能以及是否可以只更新初始状态的“数据”部分而不必传播它(...clientData

4

4 回答 4

2

这是不可能的,因为从useState钩子返回的 set 方法完全用你传递的值替换了先前的状态值。

一种可能性是用多个钩子分隔您的状态,这将为您提供更精细的更新组件状态的方法:

/* Separate your state across multiple hooks */
const [data, setData] = useState({});
const [product, setProduct] = useState('profile');

useEffect(() => {
    getProducts(1).then(res =>
      /* Only update data portion of state via setData hook */
      setData(res.data)
    );
 }, []);
于 2019-08-27T03:01:16.527 回答
1

这里有几个选择...

1) 分开以下...

const [clientData, setClientData] = useState({
    data: {},
    product: 'profile'
 });

进入...

const [clientData, setClientData] = useState({});
const [clientProduct, setClientProduct] = useState('profile');

然后您可以更新您需要的数据部分。在您上面列出的情况下,这可能是推荐的。或者...

2)使用像'immer'这样的库,它允许您通过简单地修改现有的状态树来创建新的状态树......

import produce from 'immer';

...

const [clientData, setClientData] = useState({
  data: {},
  product: 'profile'
});

useEffect(() => {
  getProducts(1).then(res =>
    setClientData(produce(clientData, draft => {
      draft.data = res.data;
    }));
  );
}, []);

Immer 是一个很棒的图书馆,你可以在这里了解更多

于 2019-08-27T03:03:05.833 回答
1

这对于 useState 是不可能的。不过,使用useReducer是可能的。

于 2019-08-27T03:03:51.993 回答
0

如前所述,最佳实践是在多个钩子之间拆分此状态,但是,实际上可以useState()使用如下函数来做到这一点:

const setClientDataSelectively = ({data=null, product=null}) => {
    setClientData((prevState) => ({
        data: data !== null ? data : data,
        product: product !== null ? product : product,
    }));
}

参数默认为null,然后使用prevState对象和条件运算符,您可以检查是否实际传递了某些内容并相应地进行属性。

于 2021-10-20T18:47:00.813 回答