为什么会渲染该组件?

huangapple go评论63阅读模式
英文:

why does this render the component?

问题

尽管我掌握了基本知识,但似乎我仍然在挣扎,我有这个示例

const Component = () => {
  const [state, setState] = useState("");
  useEffect(() => {
    console.log("useEffect");
    setState("Nebil");
  }, [state]);

  console.log("component rerender ", state);
};
export default Component;

使用上述代码,我看到以下输出

component rerender
useEffect
component rerender Nebil 
useEffect
component rerender Nebil 

我想知道为什么第二次触发 useEffect 时会更新状态并导致重新渲染。我认为当值等于 "Nebil" 且我们将状态设置为 "Nebil" 时,因为它是一个字符串,这不会导致组件重新渲染。你能解释一下吗?

注意:我不使用 strict mode。

英文:

Even though I have the basics but it seems I'm still struggling, I have this example

const Component = () => {
  const [state, setState] = useState("");
  useEffect(() => {
    console.log("useEffect");
    setState("Nebil");
  }, [state]);

  console.log("component rerender ", state);
};
export default Component;

With the above code I see this output

component rerender
useEffect
component rerender Nebil 
useEffect
component rerender Nebil 

I wonder why the second time useEffect fires, it updates the state and causes a render, I thought that when the value is equal to "Nebil" and we set the state to "Nebil" since it is a string, this will not render the component. can you please explain this to me?

note: I don't use strictmode

答案1

得分: 3

Sure, here is the translated content:

组件重新渲染
默认状态是“”

useEffect
useEffect 是由默认状态“”触发的

组件重新渲染 Nebil
useEffect 中,状态已经被更改为“Nebil”

useEffect
因为状态已经更改,useEffect 由状态“Nebil”触发

组件“rerender” Nebil
由于 useEffect 已经被触发,函数(Component 本身是一个函数)被执行,但即使您看到 console.log 输出,虚拟 DOM 不会被更新,因为与之前相同,因此不会触发额外的渲染。您应该尝试添加 return 语句并使用开发工具来突出显示哪部分 DOM 已更新,我认为 React 开发工具可以做到这一点。

英文:

Well, here and explenation on each console.log

component rerender
The default state is ""

useEffect
useEffect is triggered by the default state ""

component rerender Nebil
In useEffect, the state have been changed to "Nebil"

useEffect
since the state is changed, useEffect is triggered by the state "Nebil"

component "rerender" Nebil
since useEffect have been triggered, the function (Component itself is a function) is executed but, even if you see the console.log output, Virtual DOM will not be updated, since it is the same as before, so no additional render will be triggered. You should try to add the return statment and use a developer tool that higligths in green which part of the DOM is updated, I think React dev tools have something to do so.

答案2

得分: 3

useEffect 是一个 React Hook,它允许您将组件与外部系统同步,或者在您的情况下,您正在将其与您的状态同步。

通过将依赖状态传递给 useEffect,React 将比较状态与其先前的值。因此,因为您在 useEffect 内部设置了状态,这将导致组件重新渲染,因为状态从初始值发生了变化。这是发生的情况:

  1. 初始 组件渲染
  2. 在初始渲染上执行 useEffect
  3. 由于设置了状态,再次 组件渲染
  4. 执行 useEffect,因为依赖关系已从“”更改为“Nebila”
  5. 现在我们将不会执行 useEffect,因为您正在设置相同的状态值,如果您在 useEffect 内部初始化一个新对象,将会进入无限循环!

尝试将初始状态设置为“Nebil” useState("Nebil"),useEffect 仅在初始渲染时触发一次。

请确保删除 strictMode,因为您的组件将额外重新渲染一次,以查找由不纯粹渲染引起的错误。

我创建了一个沙盒来检查渲染次数 https://codesandbox.io/s/long-cookies-s4vjg6?file=/src/App.js

以下是一些有用的参考链接:

英文:

useEffect is a React Hook that lets you synchronize a component with an external system or in your case you are synchronizing it with your state.

By passing the dependency state to the useEffect, React will compare the state with its previous value. Therefore, because you are setting the state inside the useEffect it will cause the component to re-render because the state change from initial value. Here is what is happening:

  1. initial component render
  2. executing useEffect on inital render
  3. component render again because of setState
  4. executing useEffect because dependency has changed from "" to "Nebila"
  5. now we will not execute useEffect because you are setting the same state value, if you initialize a new object inside the ue you will enter an infinite loop!

Try setting your initial state to "Nebil" useState("Nebil"), the useEffect will only be triggered once on initialRender.

Please make sure to remove strictMode because your components will re-render an extra time to find bugs caused by impure rendering.

I created a sandbox to check the render count https://codesandbox.io/s/long-cookies-s4vjg6?file=/src/App.js

Here are some helpful references:

huangapple
  • 本文由 发表于 2023年6月27日 17:15:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/76563361.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定