我想在我的对象中将active更改为true,在控制台日志中,我具有状态的更新版本,但是我无法更新状态本身,我觉得这是错误的做法。任何帮助都将是非常棒的谢谢,可以肯定的是,某处有类似的帖子,但是我没有找到任何东西。
const [components, setComponents] = useState([
{
compName: "Weather",
path: 'weather',
active: false
},
{
compName: "Tasks",
path: 'tasks',
active: false
},
])
function onActivateHandler(){
setComponents((prevComponents) => {
const copy = [...prevComponents]
let newState = {...copy[1]}
newState.active = true
console.log(newState)
return {...prevComponents}
})
}
答案 0 :(得分:0)
我认为您只需要为整个数组生成一个新引用即可。
我注意到的另一件事是您正在从setComponents()
函数返回一个对象。由于状态变量components
是一个数组,我认为您需要返回一个数组。
另外,将onActivateHandler()
方法编写为箭头函数,以将其绑定到组件上下文,以防万一,通常是您要执行的操作。
我会这样写(我切换活动值正好演示):
const myComponent = () => {
const [components, setComponents] = useState([
{
compName: "Weather",
path: "weather",
active: false,
},
{
compName: "Tasks",
path: "tasks",
active: false,
},
]);
const onActivateHandler = () => {
setComponents((prevComponents) => {
// update the array reference
const newState = [...prevComponents];
newState[1].active = !newState[1].active;
// Your state variable is an array,
// so you need to return an array
return [...prevComponents];
});
};
return (
<>
<button onClick={onActivateHandler}>Click</button>
<div>{components[1].active ? 'active' : 'inactive'}</div>
</>
)
};
正如下面的lawrence-witt
所述,在某些情况下,未在新数组内创建新对象可能导致不重新渲染,但是在您的简单情况下,上面的代码可以正常工作,因为数组引用的作用是跟踪,而不是内部对象的引用。您可以根据需要将newState[1]
散布到一个新对象中,但是您需要从状态数组中删除较旧的对象。
干杯!
答案 1 :(得分:0)
您只需要将克隆的,修改后的对象与其余prevComponents
一起返回。目前,您仅返回旧状态,因此不会发生任何变化(除了您意外返回的是对象,而不是数组之外的事实)。
编辑:现在看起来不太漂亮,但是很安全。
function onActivateHandler(){
setComponents((prevComponents) => {
const copy = [...s];
const newState = {...copy.splice(1, 1)[0]}
newState.active = true;
return [...copy, newState];
})
}