如何在使用状态挂钩更新状态时覆盖具有相同键的对象
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
)
)
};
我对反应有点陌生,所以也许我对更新功能组件中的状态一无所知。有人可以帮我吗?谢谢!
方法是在设置状态之前找到正确的对象并更改其值:
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);
};
虽然我相信这可以解决您的问题,但我认为如果您将过滤器存储在数组中会更好,这意味着对象结构为:
[[l1,v1], [l1, v2]]
这样一来,过滤器 1 就是过滤器数组中的索引 0,依此类推。所以做你想做的事,你将有一个接收过滤器编号、标签和值的函数:
const handleChange = (filter, label, value) => {
let newFilters = [...filterValues] // A new copy of the state.
newFilters[filter - 1] = [label, value];
setFilterValues(newFilters);
};
请注意,如果您收到过滤器编号 1,表示第一个过滤器,您想要访问过滤器数组中的位置 0。
在对象(即 "Map" 或 "Dictionary")而不是数组中按键存储过滤器数组标签-值对,允许您通过恒定时间 (O(1)) 查找key通过key更新filter的值(copying and return a new state value is OFC still O(n)).
此外,使用功能状态更新来正确访问以前的状态并排队状态更新。
const [filterValues, setFilterValues] = useState({ f1: ["l","v"] });
const handleChange = (filter, label, value) => {
setFilterValues(prevFilterValues => ({
...prevFilterValues, // copy previous state
[filter]: [label, value], // set the value for filter key
}));
};
示例:
handleChange('f1', 'l1', 'v1');
// filterValues = { f1: ["l1", "v1"] }
handleChange('f2', 'l2', 'v2');
// filterValues = {
// f1: ["l1", "v1"],
// f2: ["l2", "v2"],
// }
handleChange('f1', 'l3', 'v3');
// filterValues = {
// f1: ["l3", "v3"],
// f2: ["l2", "v2"],
// }
演示:
//const [filterValues, setFilterValues] = useState({ f1: ["l","v"] });
// Manual mock for useState return values
let filterValues = { f1: ["l","v"] };
setFilterValues = stateUpdater => filterValues = stateUpdater(filterValues);
const handleChange = (filter, label, value) => {
setFilterValues(prevFilterValues => ({
...prevFilterValues, // copy previous state
[filter]: [label, value], // set the value for filter key
}));
};
// Start Demo
console.log('initial filterValues', filterValues); // { f1: ["l", "v"] }
handleChange('f1', 'l1', 'v1');
console.log('filterValues', filterValues); // { f1: ["l1", "v1"] }
handleChange('f2', 'l2', 'v2');
console.log('filterValues', filterValues); // { f1: ["l1", "v1"], f2: ["l2", "v2"] }
handleChange('f1', 'l3', 'v3');
console.log('filterValues', filterValues); // { f1: ["l3", "v3"], f2: ["l2", "v2"] }
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);
}
}
});
};
我想在选择新过滤器时更新状态。初始状态显示我瞄准的对象结构。例如,我添加了一个过滤器选择(例如"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
)
)
};
我对反应有点陌生,所以也许我对更新功能组件中的状态一无所知。有人可以帮我吗?谢谢!
方法是在设置状态之前找到正确的对象并更改其值:
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);
};
虽然我相信这可以解决您的问题,但我认为如果您将过滤器存储在数组中会更好,这意味着对象结构为:
[[l1,v1], [l1, v2]]
这样一来,过滤器 1 就是过滤器数组中的索引 0,依此类推。所以做你想做的事,你将有一个接收过滤器编号、标签和值的函数:
const handleChange = (filter, label, value) => {
let newFilters = [...filterValues] // A new copy of the state.
newFilters[filter - 1] = [label, value];
setFilterValues(newFilters);
};
请注意,如果您收到过滤器编号 1,表示第一个过滤器,您想要访问过滤器数组中的位置 0。
在对象(即 "Map" 或 "Dictionary")而不是数组中按键存储过滤器数组标签-值对,允许您通过恒定时间 (O(1)) 查找key通过key更新filter的值(copying and return a new state value is OFC still O(n)).
此外,使用功能状态更新来正确访问以前的状态并排队状态更新。
const [filterValues, setFilterValues] = useState({ f1: ["l","v"] });
const handleChange = (filter, label, value) => {
setFilterValues(prevFilterValues => ({
...prevFilterValues, // copy previous state
[filter]: [label, value], // set the value for filter key
}));
};
示例:
handleChange('f1', 'l1', 'v1');
// filterValues = { f1: ["l1", "v1"] }
handleChange('f2', 'l2', 'v2');
// filterValues = {
// f1: ["l1", "v1"],
// f2: ["l2", "v2"],
// }
handleChange('f1', 'l3', 'v3');
// filterValues = {
// f1: ["l3", "v3"],
// f2: ["l2", "v2"],
// }
演示:
//const [filterValues, setFilterValues] = useState({ f1: ["l","v"] });
// Manual mock for useState return values
let filterValues = { f1: ["l","v"] };
setFilterValues = stateUpdater => filterValues = stateUpdater(filterValues);
const handleChange = (filter, label, value) => {
setFilterValues(prevFilterValues => ({
...prevFilterValues, // copy previous state
[filter]: [label, value], // set the value for filter key
}));
};
// Start Demo
console.log('initial filterValues', filterValues); // { f1: ["l", "v"] }
handleChange('f1', 'l1', 'v1');
console.log('filterValues', filterValues); // { f1: ["l1", "v1"] }
handleChange('f2', 'l2', 'v2');
console.log('filterValues', filterValues); // { f1: ["l1", "v1"], f2: ["l2", "v2"] }
handleChange('f1', 'l3', 'v3');
console.log('filterValues', filterValues); // { f1: ["l3", "v3"], f2: ["l2", "v2"] }
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);
}
}
});
};