即使我通过相同的参考,可以反应usestate rerender?
我知道的是,如果我们通过同一状态,我将不会恢复,我自己对其进行了测试,但是仅在组件首次启动时才起作用,而初始状态传递给了Usestate。 但是在下面的示例中,即使我传递了相同的参考,美国植物也会重新启动组件,也知道状态不会改变。 带有控制台的图片显示了这种行为。
const arr = [
{ name: 'Khaled', id: 0 },
{ name: 'Mohamed', id: 1 },
{ name: 'Ahmed', id: 2 },
{ name: 'Mohsen', id: 3 },
];
function App() {
console.log('num $1');
const [same, setSame] = useState({});
useEffect(() => {
console.log('num $3');
const test = arr.find((el) => el.id === 0);
console.log(Object.is(same, test));
setSame(test);
}, [same]);
console.log('num $2');
return <div>welcome</div>;
}
What I know is that useState will not rerender if we pass the same state, and I test it by myself, but it worked only the first time the component rerendered, with an initial state passed to useState.
But in the example below, the useState rerenders the component even if I pass the same reference, also useEffect knows that the state does not changed.
The picture with console.logs shows that behavior.
const arr = [
{ name: 'Khaled', id: 0 },
{ name: 'Mohamed', id: 1 },
{ name: 'Ahmed', id: 2 },
{ name: 'Mohsen', id: 3 },
];
function App() {
console.log('num $1');
const [same, setSame] = useState({});
useEffect(() => {
console.log('num $3');
const test = arr.find((el) => el.id === 0);
console.log(Object.is(same, test));
setSame(test);
}, [same]);
console.log('num $2');
return <div>welcome</div>;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
组件是两次渲染的,因为您具有相同状态的初始值,该值为空{}。在使用效果内部,您可以使用一个新对象更新此状态,然后使用效果触发已添加到相同状态的新值。这是您数组中的匹配对象。然后重新渲染组件,这就是为什么您进入控制台的原因。
这是您上次评论的更新。
与之那样。这将使我们的使用效率一旦看到相同被更新。然后,它将像我之前提到的那样重新渲染组件。
这里相同具有相同的数据。但是它们是不同的,因为第一个相同是[],第二个是{}。因此,这是国家的变化。然后使用效率将重新渲染。
The component is rendered twice because you have the initial value for the same state which is empty { }. inside the useEffect you update this state with a new object then the useEffect triggers a new value that has been added to the same state. which is the matched object from your array. then the component re-rendered and that's why you got in the console.log the true value.
That's an update for your last comment.
with that. this will lead us that the useEffect once it sees the same get updated. then it will re-render the component as I mentioned before.
here same have the same data. but they are different because the first same is [] and the second one is { }. so that's a change in the state. then useEffect will re-render.
以前的答案很好地解释了这一点。为了没有状态重新渲染,您必须使用原始数组初始化它。
请注意,这仅适用于参考类型。 Hook不会对对象或数组进行比较,它只是检查参考是否更改。这对价值类型不起作用。
Previous answer explains it perfectly. To not have the state re-render you must initialize it with the original array.
Make note that this only works for the reference types. Hook doesn’t perform a comparison on objects or arrays, it simply checks whether the reference changes or not. This does not work for value types.
我对您到底要做什么有些困惑,但这是我对此的理解,并希望能解决您的问题。
重要的是要记住,无论如何,
useffect()
都会在组件安装(第一个渲染)上调用。这就是为什么您的组件正在吐出num $ 3
首次渲染的控制台登录,即使从逻辑上看,您也希望它不会以setSame()()函数在
usefeft()
本身之内。出于以看似相同的对象设置状态之后的组件重新订阅者的原因,在这里要记住的另一个重要的事情(通常使用JavaScript)是参考等值。考虑以下内容:
即使从逻辑上讲,您也希望两个相同的对象将其评估为两个平等,就JavaScript而言,它们并不相同。因此,当您将对象传递到
setSame()
函数外观与相同
状态相同的函数时,JavaScript考虑了它是改变状态的,并提示在React中重新渲染。希望这会有所帮助。
I'm slightly confused on what exactly you are trying to do, but here's my understanding of this and hopefully an answer to your problem.
Its important to remember that a
useEffect()
will be called on component mount (first render) no matter what. This is why your component is spitting out thenum $3
console log on first render, even though logically you would expect it not to run at-all, as the onlysetSame()
function is within theuseEffect()
itself.For the reason the component re-renders after the state is set with a seemingly-identical object, another important thing to remember here (and with JavaScript in general) is referential equality. Consider the following:
Even though logically, you would expect two identical objects to evaluate as two equals, as far as JavaScript is concerned, they are not the same. So, when you pass an object into the
setSame()
function that looks the same as what thesame
state is at that time, JavaScript considers it a change of state and prompts a re-render in React.Hope this helps.