Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/370.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

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 如何使用useContext防止组件中出现不必要的渲染?_Javascript_Reactjs - Fatal编程技术网

Javascript 如何使用useContext防止组件中出现不必要的渲染?

Javascript 如何使用useContext防止组件中出现不必要的渲染?,javascript,reactjs,Javascript,Reactjs,我想知道如何避免对不接收道具但使用useContext的子组件进行不必要的更新 我在Child2组件中添加了React.memo,以便进行一些演示测试 如您所见,当我更改使用上下文将数据传递给child1的输入值时,Child2不会重新呈现,因为React.memo会阻止这种行为 如何防止Child1中出现不必要的渲染?我知道React.memo不起作用,因为它需要道具,而在上下文中,这不会发生,因为没有道具被传递给这个组件 App.js function App() { const [na

我想知道如何避免对不接收道具但使用useContext的子组件进行不必要的更新

我在Child2组件中添加了React.memo,以便进行一些演示测试

如您所见,当我更改使用上下文将数据传递给child1的输入值时,Child2不会重新呈现,因为React.memo会阻止这种行为

如何防止Child1中出现不必要的渲染?我知道React.memo不起作用,因为它需要道具,而在上下文中,这不会发生,因为没有道具被传递给这个组件

App.js

function App() {
  const [name, setName] = useState("Radha");
  const [count, setCount] = useState(0);

  const increaseCount = () => {
    setCount(prevState => prevState + 1);
  };

  const value = useMemo(() => ({ name }), [name]);
  return (
    <div className="App">
      <Child2 count={count} />
      <button onClick={increaseCount}>Increase</button>

      <input
        type="text"
        value={name}
        onChange={event => setName(event.target.value)}
      />
      <SillyContext.Provider value={value}>
        <Child1 />
      </SillyContext.Provider>
    </div>
  );
}
孩子2

const Child2 = React.memo(function(props) {
  console.log("[Child2 Ran!]");
  return <div>[Child2] - Count: {props.count}</div>;
});
您可以在Child1组件内部使用。这并不能解决重新招标的问题,但它是一种改进

我们可以让我们的代码更详细一点,但要把它保存在 通过在UseMoom中包装返回值并指定 它的依赖性。我们的组件仍然会重新执行,但会做出反应 如果所有useMemo输入都相同,则不会重新呈现子树

const{useState,useEffect,createContext,useContext,UseMoom}=React; const SillyContext=createContext; const Child2=React.memo{count}=>{ 返回计数:{Count} } 常量Child1==>{ const{name}=useContextSillyContext; 返回usemo=>{ console.log'Child1'; 回来 子1:{name} },[姓名] } 常量应用==>{ const[count,setCount]=useState0; 常量递增计数==>{ setCountprevState=>prevState+1 } 回来 增长 } ReactDOM.render , document.getElementById'root' ;
更新计数时,Child1重新呈现的主要问题是,您每次都向上下文提供程序传递一个新的对象引用

此外,如果应用程序组件重新呈现,则其中呈现的所有元素都将重新呈现,除非它们实现了记忆化或是PureComponent或使用shouldComponentUpdate

可以进行2次更改以修复重新渲染

用React.memo包装Child1 使用UseMoom将作为值传递给提供程序的对象记录下来 App.js

function App() {
  const [name, setName] = useState("Radha");
  const [count, setCount] = useState(0);

  const increaseCount = () => {
    setCount(prevState => prevState + 1);
  };

  const value = useMemo(() => ({ name }), [name]);
  return (
    <div className="App">
      <Child2 count={count} />
      <button onClick={increaseCount}>Increase</button>

      <input
        type="text"
        value={name}
        onChange={event => setName(event.target.value)}
      />
      <SillyContext.Provider value={value}>
        <Child1 />
      </SillyContext.Provider>
    </div>
  );
}
孩子2

const Child2 = React.memo(function(props) {
  console.log("[Child2 Ran!]");
  return <div>[Child2] - Count: {props.count}</div>;
});
儿童1

const Child1 = React.memo(function() {
  const sillyContext = useContext(SillyContext);
  console.log("[Child 1 ran]");
  return (
    <div>
      <div>[Child 1]: {sillyContext.name}</div>
    </div>
  );
});

这没用Child2仍在重新呈现,只是没有重新运行useMemo并返回相同的jsx代码。-您可以说这很有帮助,因为jsx代码没有改变。如果里面没有另一个子组件并且没有使用useMemo,则不需要重新运行那段jsx代码,但不会重新影响真正的DOM。==>这对更新的答案没有帮助。非常感谢。谢谢你的洞察力!我认为React.memo不会在Child1内部触发,因为它是一个不接收道具的组件。我已经考虑过隔离提供者提供的对象的需要,但我不理解React.memo如何理解,在这种特定情况下,提供者传递的内容可以被视为道具,方法是包装Child1+提供者的obj。你能解释一下为什么吗?一个没有收到道具的组件,如果父组件重新渲染,它也会重新渲染,这就是为什么memo会派上用场的原因。就使用上下文而言,它的值不是由props提供的
const Child1 = React.memo(function() {
  const sillyContext = useContext(SillyContext);
  console.log("[Child 1 ran]");
  return (
    <div>
      <div>[Child 1]: {sillyContext.name}</div>
    </div>
  );
});