在属性更改时重新渲染一个功能组件

20 浏览
0 Comments

在属性更改时重新渲染一个功能组件

子组件接受一个属性并进行计算以显示值。在首次加载时,它能正常工作,但当父组件传递新值时,没有更新。

父组件:

function Parent() {
  const [v, setV] = useState(0);
  const addNewValue = () => {
    setV(generateValue({ type: 'mv', gId: 3 })); // generateValue是一个在每次调用时返回整数的函数
  }
  return (
    <>
      
      
    
  )
}

Child.js:

function Child({ value }) {
  const [baseValue, setBaseValue] = useState(value);
  useEffect(() => {
    const calculate = calculate(baseValue);
    setBaseValue(calculate);
  }, [baseValue]);
  return (
    {baseValue}
  )
}

0
0 Comments

当将值作为prop传递给useState时,只会在挂载阶段改变baseValue,而不会在将来的更新中改变值prop。如果要以某种方式进行优化计算,可以将计算出的值记忆起来,否则,似乎移除状态并使用props就可以完成工作。查看无控制组件。

解决方法是使用useMemo将计算结果缓存起来,然后将value作为依赖项传递给useMemo,以便在value发生变化时重新计算baseValue。

下面是修改后的代码示例:

function Child({ value }) {
  const baseValue = useMemo(() => calculate(baseValue), [value]);
  return (
    
{baseValue}
); }

这样,当value发生变化时,Child组件将重新渲染,并且baseValue将使用最新的value进行计算。

0
0 Comments

当我们在一个已经挂载的组件中使用useEffect钩子函数时,如果我们希望在prop发生变化时重新渲染函数组件,可能会遇到一个问题。问题在于,当组件挂载时,useEffect函数不会触发,因为在挂载时,prop的值并没有发生改变。然而,当prop的值发生变化时,我们希望重新渲染组件。

要解决这个问题,我们可以更新我们的useEffect函数。我们可以将需要触发重新渲染的prop作为useEffect的第二个参数传入。这样,当prop的值发生变化时,useEffect函数就会重新触发,从而重新渲染组件。

具体实现如下:

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

在这个例子中,我们使用了一个函数calculate来计算baseValue的值。当prop value发生变化时,我们重新计算baseValue,并通过setBaseValue函数更新state。这样,组件就会重新渲染,并展示新的baseValue。

通过这种方式,我们可以实现在prop发生变化时重新渲染函数组件的效果。这对于需要根据不同的prop值来展示不同内容的组件非常有用。

0
0 Comments

问题的原因是在使用useState时,传递的参数只会在第一次渲染时使用一次,所以当value更新时,你永远看不到任何变化。然而,Child组件仍然重新渲染。

解决方法是确保useEffect只依赖于value,因为这是它实际上需要操作的内容。否则,你会陷入无限循环,因为每次baseValue更改时,你都在更新它。

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

还要注意,将props中的值存储在状态中通常是一种反模式。React文档提供了一个非常有用的检查清单,列出了不应该包含在状态中的内容。

1. 它是通过props从父组件传递过来的吗?如果是,那么它可能不是状态。

2. 它在时间上保持不变吗?如果是,那么它可能不是状态。

3. 你能根据组件中的其他状态或props计算出它吗?如果可以,那么它不是状态。

根据上述检查清单,这个问题可能属于第三种情况(如果不了解完整的用例,无法确定)。在这种情况下,你不应该在子组件中使用局部状态。如果是这样的话,你应该在每次渲染时直接调用calculate,或者如果计算量很大,可以使用记忆化。

0