我可以在useEffect挂钩中设置状态

可以说我有一些状态依赖于其他状态(例如,当A更改时,我希望B更改)。

创建一个观察A并将B设置在useEffect钩内的钩子是否合适?

效果是否会级联,从而在我单击按钮时会触发第一个效果,从而导致b发生变化,从而导致第二个效果在下一次渲染之前触发?这样构造代码是否有性能下降?

let MyComponent = props => {
  let [a, setA] = useState(1)
  let [b, setB] = useState(2)
  useEffect(
    () => {
      if (/*some stuff is true*/) {
        setB(3)
      }
    },
    [a],
  )
  useEffect(
    () => {
      // do some stuff
    },
    [b],
  )

  return (
    <button
      onClick={() => {
        setA(5)
      }}
    >
      click me
    </button>
  )
}
小哥Tom2020/03/19 14:33:06

效果始终在渲染阶段完成后执行,即使您将setState放在一个效果中,另一个效果也将读取更新的状态并仅在渲染阶段之后对其执行操作。

话虽如此,最好以相同的效果采取两种行动,除非有可能b由于其他原因而改变的可能性,而不是changing a在这种情况下,您也希望执行相同的逻辑

小卤蛋卡卡西2020/03/19 14:33:05

一般来说,使用setStateinside useEffect将创建一个无限循环,您很可能不想引起该循环。该规则有几个例外,我将在以后讨论。

useEffect在每次渲染之后调用,并在其中setState进行使用时,它将导致组件重新渲染,从而进行调用useEffect,依此类推。

使用useStateinside useEffect不会导致无限循环的一种常见情况是,当您将一个空数组作为第二个参数传递给useEffectlike时useEffect(() => {....}, []),这意味着效果函数应该被调用一次:仅在第一次安装/渲染之后。当您在组件中进行数据获取并且想要以组件的状态保存请求数据时,此方法被广泛使用。

LEY古一逆天2020/03/19 14:33:05

useEffect可以挂钩到某个道具或状态。因此,您需要做的是避免无限循环挂钩的事情是将某些变量或状态绑定到效果上

例如。

useEffect(myeffect, [])

仅当组件渲染后,上述效果才会触发。这类似于componentDidMount生命周期

const [something, setSomething] = withState(0)
const [myState, setMyState] = withState(0)
useEffect(() => {
  setSomething(0)
}, myState)

上面的效果只会触发我的状态已更改,这类似于componentDidUpdate,除了不是每个更改的状态都会触发其

您可以通过此链接阅读更多详细信息