我在react 16.10.2中使用usestate挂钩,但是在usetate挂钩中使用自定义函数更新初始状态后,react不会触发重新渲染(未渲染OtherComponent),这是我的react组件:
import React, { useState, useEffect } from 'react';
import OtherComponent from "./OtherComponent";
function Component(props) {
const [render, setRender] = useState({0:false, 1:false});
const display_data = (index) => {
setRender((prevState) => {
prevState[index] = !prevState[index];
return prevState;
});
};
return (
<>
{{custom_json_array}.map((record, index) => {
return (
<div>{teacher_render[index] ? 'true' : 'false'}</div>
<button onClick={() => display_data(index)}>change state</button>
{render[index] ? <OtherComponent /> : ''}
</div>)
})}
</>
);
}
但是奇怪的是,如果我从钩子更新器函数返回{... prevState},一切正常,并且触发了重新渲染! 我完全感到困惑,为什么反应会表现得如此?!
答案 0 :(得分:2)
我认为问题是您正在突变render
?
<button
onClick={() => setRender({ ...render, [index]: !render[index] })}
>
change state
</button>
在此示例中,单击名称以查看自定义组件,然后再次单击以隐藏
https://codesandbox.io/s/dark-wind-3310q
const CustomComponent = () => (
<div style={{ marginLeft: 10, background: "red" }}>I'm Selected!</div>
);
function App() {
const [people] = useState([
{ id: 0, name: "Mario" },
{ id: 1, name: "Luigi" },
{ id: 2, name: "Peach" }
]);
const [selected, setSelected] = useState({});
return (
<div>
{people.map(({ id, name }) => (
<div
style={{ display: "flex", cursor: "pointer" }}
key={id}
onClick={() => setSelected({ ...selected, [id]: !selected[id] })}
>
{name}
{selected[id] && <CustomComponent />}
</div>
))}
</div>
);
}
这是您发布的错误代码的简化示例,以显示没有更新发生:
https://codesandbox.io/s/goofy-williamson-22fgs
function App() {
const [obj, setObj] = useState({ name: "Mario" });
const change = () => {
// The following commented code will display no change
// obj.name = "Peach";
// setObj(obj);
setObj({ ...obj, name: "Peach" });
};
return (
<div className="App">
<div>{obj.name}</div>
<button onClick={change}>Change!</button>
</div>
);
}
答案 1 :(得分:0)
您的onclick处理程序在标记中称为display_teacher_data
,但在组件中称为display_data
。将它们设置为相同,以便状态更改。