Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 当道具不变时,为什么React会重新渲染儿童?_Javascript_Reactjs_Typescript - Fatal编程技术网

Javascript 当道具不变时,为什么React会重新渲染儿童?

Javascript 当道具不变时,为什么React会重新渲染儿童?,javascript,reactjs,typescript,Javascript,Reactjs,Typescript,考虑以下示例: 导入“/styles.css”; 从“React”导入React; 功能儿童(道具){ 常数计数器=道具计数器2; console.log(“重新呈现子项”); 返回( 计数器2值={counter} ); } 导出默认函数App(){ const[counter,setCounter]=React.useState(0); 常量[counter2]=React.useState(0); 返回( 计数器值={counter} setCounter((c)=>c+1)}>incre

考虑以下示例:

导入“/styles.css”; 从“React”导入React; 功能儿童(道具){ 常数计数器=道具计数器2; console.log(“重新呈现子项”); 返回( 计数器2值={counter}

); } 导出默认函数App(){ const[counter,setCounter]=React.useState(0); 常量[counter2]=React.useState(0); 返回( 计数器值={counter}

setCounter((c)=>c+1)}>increment ); }
子组件
不依赖于父状态
计数器
,但当我单击按钮时,我可以看到每次单击时都会打印
重新渲染
日志。如果我没有弄错的话,这意味着
子组件将被重新渲染。我的问题是为什么?它不应该重新渲染,因为道具没有改变


代码沙盒:

由于React的生命周期,当您使用功能组件时,它也被认为是无状态的,并且每当其父组件中有更新时,无论传递到子组件的道具是否有更改,它都将重新呈现

有两种方法可以改变这种行为

  • 使用类组件并决定是否使用
    shouldComponentUpdate

  • 或者使用
    React.memo
    的推荐方式

  • 导入“/styles.css”; 从“React”导入React; 功能儿童(道具){ 常数计数器=道具计数器2; console.log(“重新呈现子项”); 返回( 计数器2值={counter}

    ); } const MemoChild=React.memo(子对象); 导出默认函数App(){ const[counter,setCounter]=React.useState(0); 常量[counter2]=React.useState(0); 返回( 计数器值={counter}

    setCounter((c)=>c+1)}>increment {/* */} ); }
    更多关于
    React.memo的信息,请参见

    如果您的组件在给定相同道具的情况下呈现相同的结果,您可以将其包装在调用React.memo中,以便在某些情况下通过记忆结果来提高性能。这意味着React将跳过渲染组件,并重用上次渲染的结果


    这个答案是正确的,您可以使用React.memo,但在开始使用之前,请查看一些文章,以确定何时使用它是有价值的。
    使用不当可能会损害性能。

    因为默认情况下,重新渲染的组件的所有子组件都会重新渲染。为了防止子组件重新呈现,请考虑使用<代码> Real.MeMo < /C> >找到一个优秀的相同:
    import "./styles.css";
    import React from "react";
    
    function Children(props) {
      const counter = props.counter2;
      console.log("re-rendering children");
      return (
        <div className="App">
          <p>counter2 value = {counter} </p>
        </div>
      );
    }
    
    const MemoChild = React.memo(Children);
    
    export default function App() {
      const [counter, setCounter] = React.useState(0);
      const [counter2] = React.useState(0);
      return (
        <div className="App">
          <p>counter value = {counter} </p>
          <button onClick={(e) => setCounter((c) => c + 1)}>increment</button>
          <MemoChild counter2={counter2} />
          {/* <Children counter2={counter2} /> */}
        </div>
      );
    }