我已经初始化了一个数组状态,当我更新它时,我的组件不会重新呈现。下面是一个最小的概念证明:
function App() {
const [numbers, setNumbers] = React.useState([0, 1, 2, 3]);
console.log("rendering...");
return (
<div className="App">
{numbers.map(number => (
<p>{number}</p>
))}
<input
type="text"
value={numbers[0].toString()}
onChange={newText => {
let old = numbers;
old[0] = 1;
setNumbers(old);
}}
/>
</div>
);
}
根据这段代码,似乎输入应该包含数字0来开始,并且任何时候它被改变,状态也应该改变。在输入中输入“02”后,App组件不会重新渲染。然而,如果我在onChange函数中添加了一个setTimeout,它在5秒后执行,它显示数字确实已经更新。
对于组件不更新的原因有什么想法吗?
这里是一个概念验证的代码和框。
Others have already given the technical solution. To anyone confused as to why this happens, is because setSomething() only re renders the component if and only if the previous and current state is different. Since arrays in javascript are reference types, if you edit an item of an array in js, it still doesn't change the reference to the original array. In js's eyes, these two arrays are the same, even though the original content inside those arrays are different. That's why setSomething() fails do detect the changes made to the old array.
注意,如果使用类组件并使用setState()更新状态,那么无论状态是否改变,组件总是会更新。因此,您可以将功能组件更改为类组件作为解决方案。或者按照别人提供的答案去做。
引入组件的一个数组,该数组不是钩子的数组。例如:
const [numbers, setNumbers] = useState([0, 1, 2, 3]);
var numbersModify = []; //the value you want
最后:
setNumbers(numbersModify)
修改这个numbersModify,当钩子刷新时,它将返回0 numbersModify,钩子将保持这个状态。因此,看不到更改的问题将被消除。
:D