在道具更改时重新渲染功能组件

Posted

技术标签:

【中文标题】在道具更改时重新渲染功能组件【英文标题】:re-render a functional component on prop change 【发布时间】:2021-12-22 05:58:19 【问题描述】:

子组件接受一个道具并进行计算以显示价值。在第一次加载时,它确实可以工作,但是当父级确实传递新值时,没有任何更新。

家长:

 function Parent()
       const [v, setV] = useState(0);

    const addNewValue = () =>
        setV(generateValue(type:'mv', gId: 3)); // generateValue is a function that returns an integer on each call
      

   return (<div>
          <Child value=v/>
          <Button onClick=addNewValue>Calculate</Button>
          
       </div>)

  

Child.js

 function Child(value)
       const [baseValue, setBaseValue] = useState(value);


    useEffect(()=>
      const calculate = calculate(baseValue);
      setBaseValue(calculate);
     ,[baseValue]);

   return (<div>
          <Text>baseValue</Text>
       </div>)

  

【问题讨论】:

***.com/questions/46240647/…的可能重复 @ArvindMaurya 他们不需要强制重新渲染。道具更改会自动触发重新渲染,所以如果他们没有得到这种行为,他们很可能违反了 React 的规则。但是,我相信他们会重新渲染;只是没有达到他们的预期。 【参考方案1】:

传递给useState 的参数仅在第一次渲染时使用一次,因此您将永远不会看到由于value 更新而导致的任何更改。但是,Child 组件仍在重新渲染中

您的useEffect 应该只依赖于value,因为这是它实际需要操作的。否则,您将陷入无限循环,因为每次 baseValue 更改您都会再次更新它。

useEffect(()=>
  const calculate = calculate(value);
  setBaseValue(calculate);
,[value]);

还要注意,在 state 中存储 props 的值通常是一种反模式。

React docs 提供了一个非常有用的清单,说明了应该处于什么状态。

    它是通过 props 从父级传入的吗?如果是这样,它可能不是状态: 它会随着时间的推移保持不变吗?如果是这样,它可能不是状态。 您可以根据组件中的任何其他状态或道具来计算它吗?如果是这样,它就不是状态。

这可能属于#3(不知道你的全部用例,我不能肯定地说)。在这种情况下,您根本不应该在孩子中使用本地状态。如果是这样,您应该在每次渲染时直接调用calculate,或者如果计算密集,则使用记忆化。

【讨论】:

【参考方案2】:

将 value props 传递给 useState 只会在安装阶段更改 baseValue。它不会导致 value prop 的未来更新发生变化

如果您想以某种方式以最佳方式进行计算,您可以记住计算的值,否则,似乎删除状态并使用道具就可以完成这项工作。看看Uncontrolled component

 function Child(value)

   const baseValue = useMemo(() => calculate(baseValue), [value])
   
   return (<div>
          <Text>baseValue</Text>
       </div>)
  

【讨论】:

【参考方案3】:

问题是您的效果不会触发,因为 baseValue 在已安装的组件中没有更改。这是第一次。您需要将效果更新为:

useEffect(()=>
      const calculate = calculate(value);
      setBaseValue(calculate);
     ,[value]);

【讨论】:

以上是关于在道具更改时重新渲染功能组件的主要内容,如果未能解决你的问题,请参考以下文章

Array.map 中的 React 功能组件在将函数作为道具传递时总是重新渲染

当父组件在 Next.js 应用程序中更新其道具时重新渲染 React 子组件

React Hook 功能组件防止重新渲染

即使道具没有改变,为啥还要对重新渲染组件做出反应?

React 功能组件在重新挂载后停止渲染状态更改

React 子组件不会在其状态更改时重新渲染