問題描述
如何在使用狀態掛鉤更新狀態時覆蓋具有相同鍵的對象 (How can overwrite objects that have the same key in updating State with state hooks)
我想在選擇新過濾器時更新狀態。初始狀態顯示我瞄準的對象結構。例如,我添加了一個過濾器選擇(例如“f2”),每個過濾器的標籤是固定的,所以我們可以忽略它,但值可能是“va”。這很好,但是當我想將“f2”的值更改為“vb”時,我現在在我的狀態 {“f2”:“va”} 和 {“f2”:“vb”} 中有兩個條目,而我寧願第一個被第二個覆蓋。
const [filterValues, setFilterValues] = useState([{"f1":["l","v"]}]);
const handleChange = (filter, label, value) => {
setFilterValues([
...filterValues,
{[filter]: [label, value]}
]);
};
我嘗試調用 setFilterValues 兩次(一次將條目映射到我的條件)來解決問題,但後來我什至根本沒有更新狀態:
const handleChange = (filter, label, value) => {
setFilterValues([
...filterValues,
{[filter]: [label, value]}
]);
let key = filter
setFilterValues(
filterValues.map(
el => el.key == key? { [key]: [label, value] } : el
)
)
};
我有點有點新的反應,所以也許我沒有得到更新功能組件狀態的基本知識。有人可以幫我嗎?謝謝!
參考解法
方法 1:
The way to do it would be finding the right object and changing its value before setting the state:
const handleChange = (filter, label, value) => {
const currentFilters = [...filterValues] // A new copy of the state.
const newFilters = currentFilters.map(stateFilter => stateFilter[filter] ? {[filter]: [label, value]} : stateFilter)
setFilterValues(newFilters);
};
While I believe this solves your case, I think it would be better if you stored your filters in an array, meanning an object structure of:
[[l1,v1], [l1, v2]]
That way, filter one is just index 0 on your filter array, and so on. So to do what you want, you will have a function that receives a filter number, label and value:
const handleChange = (filter, label, value) => {
let newFilters = [...filterValues] // A new copy of the state.
newFilters[filter ‑ 1] = [label, value];
setFilterValues(newFilters);
};
Please note that if you receive a filter number of 1, meanning the first filter, you want to access place 0 on the filters array.
方法 2:
const handleChange = (filter, label, value) => {
filterValues.map(el => {
for (let keys in el) {
if (keys === filter) {
el[filter] = [label, value];
setFilterValues([el]);
} else {
let newObj = { [filter]: [label, value] };
let finalArr = [...filterValues, newObj];
setFilterValues(finalArr);
}
}
});
};
(by Malte、Sagi Rika、Prakhar Mittal)