即使我通过相同的参考,可以反应usestate rerender?

发布于 2025-02-09 09:15:50 字数 790 浏览 1 评论 0原文

我知道的是,如果我们通过同一状态,我将不会恢复,我自己对其进行了测试,但是仅在组件首次启动时才起作用,而初始状态传递给了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>;
}

enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

我是男神闪亮亮 2025-02-16 09:15:50

组件是两次渲染的,因为您具有相同状态的初始值,该值为空{}。在使用效果内部,您可以使用一个新对象更新此状态,然后使用效果触发已添加到相同状态的新值。这是您数组中的匹配对象。然后重新渲染组件,这就是为什么您进入控制台的原因。

   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({}); <= initial value
    
      useEffect(() => {
        console.log('num $3');
    
        const test = arr.find((el) => el.id === 0);
        console.log(Object.is(same, test)); <= changed from false to true because the new value of same
        setSame(test); <= you updated the state
      }, [same]); <= the value of same changed from { } to a new value and that's make the component to re-render
    
      console.log('num $2');
    
      return <div>welcome</div>;
    }

这是您上次评论的更新。

import { useState, useEffect } from "react";

const arr = [
  { name: "Khaled", id: 0 },
  { name: "Mohamed", id: 1 },
  { name: "Ahmed", id: 2 },
  { name: "Mohsen", id: 3 }
];

export default function App() {
  const [same, setSame] = useState(arr);

  useEffect(() => {
    const test = arr.find((el) => el.id === 0);
    console.log(same); <= here the same is [] with 4 objecs
    setSame(test);
    console.log(same); <= here the same is { }
  }, [same]);

  return <div>welcome</div>;
}

与之那样。这将使我们的使用效率一旦看到相同被更新。然后,它将像我之前提到的那样重新渲染组件。

这里相同具有相同的数据。但是它们是不同的,因为第一个相同是[],第二个是{}。因此,这是国家的变化。然后使用效率将重新渲染。

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.

   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({}); <= initial value
    
      useEffect(() => {
        console.log('num $3');
    
        const test = arr.find((el) => el.id === 0);
        console.log(Object.is(same, test)); <= changed from false to true because the new value of same
        setSame(test); <= you updated the state
      }, [same]); <= the value of same changed from { } to a new value and that's make the component to re-render
    
      console.log('num $2');
    
      return <div>welcome</div>;
    }

That's an update for your last comment.

import { useState, useEffect } from "react";

const arr = [
  { name: "Khaled", id: 0 },
  { name: "Mohamed", id: 1 },
  { name: "Ahmed", id: 2 },
  { name: "Mohsen", id: 3 }
];

export default function App() {
  const [same, setSame] = useState(arr);

  useEffect(() => {
    const test = arr.find((el) => el.id === 0);
    console.log(same); <= here the same is [] with 4 objecs
    setSame(test);
    console.log(same); <= here the same is { }
  }, [same]);

  return <div>welcome</div>;
}

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.

帅气称霸 2025-02-16 09:15:50

以前的答案很好地解释了这一点。为了没有状态重新渲染,您必须使用原始数组初始化它。

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(arr); <= initial value is now original arr

  useEffect(() => {
    console.log('num $3');

    const test = arr.find((el) => el.id === 0);
    console.log(Object.is(same, test)); <= changed from false to true because the new value of same
    setSame(test); <= you updated the state
  }, [same]); <= the value of same changed from { } to a new value

  console.log('num $2');

  return <div>welcome</div>;
}

请注意,这仅适用于参考类型。 Hook不会对对象或数组进行比较,它只是检查参考是否更改。这对价值类型不起作用。

Previous answer explains it perfectly. To not have the state re-render you must initialize it with the original array.

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(arr); <= initial value is now original arr

  useEffect(() => {
    console.log('num $3');

    const test = arr.find((el) => el.id === 0);
    console.log(Object.is(same, test)); <= changed from false to true because the new value of same
    setSame(test); <= you updated the state
  }, [same]); <= the value of same changed from { } to a new value

  console.log('num $2');

  return <div>welcome</div>;
}

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.

浅唱ヾ落雨殇 2025-02-16 09:15:50

我对您到底要做什么有些困惑,但这是我对此的理解,并希望能解决您的问题。

重要的是要记住,无论如何,useffect()都会在组件安装(第一个渲染)上调用。这就是为什么您的组件正在吐出num $ 3首次渲染的控制台登录,即使从逻辑上看,您也希望它不会以setSame()()函数在usefeft()本身之内。

出于以看似相同的对象设置状态之后的组件重新订阅者的原因,在这里要记住的另一个重要的事情(通常使用JavaScript)是参考等值。考虑以下内容:

{} === {} //false

即使从逻辑上讲,您也希望两个相同的对象将其评估为两个平等,就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 the num $3 console log on first render, even though logically you would expect it not to run at-all, as the only setSame() function is within the useEffect() 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:

{} === {} //false

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 the same state is at that time, JavaScript considers it a change of state and prompts a re-render in React.

Hope this helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文