useEffect渲染其他组件,即使我传递空数组也会渲染。

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

useEffect renders the other components even if I pass the empty array

问题

已经在标题中指定,即使我传递空数组,useEffect 仍然会渲染其他组件。

我是一个刚开始学习 React 的女孩;我无法弄清楚为什么如果我传递空数组或 name 到依赖数组中,行为仍然相同,但实际上不应该。

这是我的代码:

App.js

export default function App() {  
    return (
      <>       
        {/* 第一次渲染 */}
        <Greet name="Eric" />   

        {/* 第二次渲染,name prop 改变 */}
        <Greet name="Stan" />   

        {/* 第三次渲染,name prop 改变 */}
        <Greet name="Butters" /> 
      </>
    )
  }

Greet.js

import { useEffect } from "react";

export default function Greet({ name }) {

    const message = `Hello, ${name}!`;  

    useEffect(() => {
        console.log(`向 ${name} 打招呼`); // 副作用!
    }, []);

    return (
        <div>{message}</div>
    )
}

从我的理解来看,使用空数组时,它只需要渲染第一个组件。

英文:

As already specified in the title, useEffect renders the other components even if I pass the empty array.

I'm a girl who is just starting to learn react; i can't figure out why if i pass empty array or 'name' in dependency array the action is still the same, but it shouldn't be.

This is my code:

App.js

export default function App() {  
    return (
      &lt;&gt;       
        {/* First render */}
        &lt;Greet name=&quot;Eric&quot; /&gt;   

        {/* Second render, name prop changes */}
        &lt;Greet name=&quot;Stan&quot; /&gt;   

        {/* Third render, name prop changes */}
        &lt;Greet name=&quot;Butters&quot; /&gt; 
      &lt;/&gt;
    )
  }

Greet.js

import { useEffect } from &quot;react&quot;;

export default function Greet({ name }) {

    const message = `Hello, ${name}!`;  

    useEffect(() =&gt; {
        console.log(`Greetings to ${name}`); // Side-effect!
    }, []);

    return (
        &lt;div&gt;{message}&lt;/div&gt;
    )
}

From what I understand, with the empty array it only needs to render the first component

答案1

得分: 3

你需要理解这里的三个概念。

首先是可重用组件。当你在 App 中写类似这样的代码时:

<Greet name="Eric" />
<Greet name="Stan" />
<Greet name="Butters" />

它在 HTML 中会类似于这样:

<div>Eric</div>
<div>Stan</div>
<div>Butters</div>

因此,在 App 组件中,你调用了 Greet 组件 3 次。它创建了 3 个 Greet 组件的实例。

其次是useEffect,当你提供一个空的依赖数组 [] 作为 useEffect 的第二个参数时,意味着该效果只会在初始渲染后运行一次。它不会在组件重新渲染时再次运行。

在你的情况下,App 组件内有 3 个 Greet 组件的实例,它在 3 个实例中运行了 1 次,所以你看到了 3 次 console.log 显示。

第三是当某些内容发生变化时,React 如何重新渲染。基本上,React 需要某种方式通知它数据已经改变,需要相应地重新渲染组件。一个简单的方法是使用useState来处理数据。

因此,示例将如下所示:

import React, { useState } from "react";

function App() {
  const [name, setName] = useState("Eric");

  return (
    <>
      <Greet name={name} />
      <button onClick={() => setName('Stan')}>Change to Stan</button>
      <button onClick={() => setName('Butters')}>Change to Butters</button>
    </>
  );
}

function Greet({ name }) {
  const message = `Hello, ${name}!`;

  useEffect(() => {
    console.log(`1st name ${name}`); // 副作用!
  }, []);

  useEffect(() => {
    console.log(`name changed ${name}`)
  }, [name])

  return (
    <div>{message}</div>
  );
}

export default App;

演示

英文:

You need to understand 3 concepts here.

First is reusable components. When you write something like this in App

&lt;Greet name=&quot;Eric&quot; /&gt;   
&lt;Greet name=&quot;Stan&quot; /&gt;   
&lt;Greet name=&quot;Butters&quot; /&gt; 

It will be similar to this in html

&lt;div&gt;Eric&lt;/div&gt;
&lt;div&gt;Stan&lt;/div&gt;
&lt;div&gt;Butters&lt;/div&gt;

So, in the App component you call the Greet 3 times. It created 3 instances of Greet component

Secondly is useEffect,
When you provide an empty dependency array [] as the second argument to useEffect, it means that the effect will only run once, after the initial render. It won't run again when the component re-renders.

In your case, you have 3 instances of Greet component inside App component, it run 1 time in 3 instances, so you see 3 console.log display.

Thirdly is how React re-render when something change. Basically, React need something to notify it that the data has changed, and it need to re-render the component accordingly. One simple way is use useState for the data.

So the example will be something like

import React, { useState } from &quot;react&quot;;

function App() {
  const [name, setName] = useState(&quot;Eric&quot;);

  return (
    &lt;&gt;
      &lt;Greet name={name} /&gt;
      &lt;button onClick={() =&gt; setName(&#39;Stan&#39;)}&gt;Change to Stan&lt;/button&gt;
      &lt;button onClick={() =&gt; setName(&#39;Butters&#39;)}&gt;Change to Butters&lt;/button&gt;
    &lt;/&gt;
  );
}

function Greet({ name }) {
  const message = `Hello, ${name}!`;

  useEffect(() =&gt; {
    console.log(`1st name ${name}`); // Side-effect!
  }, []);

  useEffect(() =&gt; {
    console.log(`name changed ${name}`)
  }, [name])

  return (
    &lt;div&gt;{message}&lt;/div&gt;
  );
}

export default App;

Demo

huangapple
  • 本文由 发表于 2023年8月10日 16:49:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/76874084.html
匿名

发表评论

匿名网友

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

确定