在道具更改时重新渲染功能组件
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 功能组件在将函数作为道具传递时总是重新渲染