如何使用 useState 更新初始状态对象的特定属性



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

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

我如何以及是否可以只更新初始状态的"数据"部分而不必传播它(...clientData)

这是不可能的,因为从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)
);
}, []);

这里有几个选项...

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是一个很棒的图书馆,你可以在这里了解更多关于它的信息

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

如前所述,最佳做法是在多个钩子之间拆分此状态,但是,实际上可以使用如下函数通过useState()来执行此操作:

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

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

相关内容

  • 没有找到相关文章

最新更新