parent调用useState更新函数时child的状态

State of child when parent calls useState update function

假设我有以下代码片段(请将其视为伪代码)

Parent.js

const [state,action]=useState(0);
return <View><Child1/><Button onPress={()=>action(1)}/></View>

Child1.js

const [state]=useState(Math.random());
return <Text>{state}</Text>

所以我的问题是,当我点击父级按钮时,Chil1 状态是否会改变。 在我的本地机器上,它似乎发生了变化。

useState的好处是,一旦安装了一个组件,在调用更新状态函数并传递一个新的状态值之前,状态值不会在重新渲染时改变。

因此,即使您的父组件按钮按下状态更改会触发子组件的重新渲染,因为子组件只是被重新渲染而不是 unmounted/remounted,Math.random() 的初始状态将保持不变一样。

useState in React: A complete guide

我不知道具体的场景是什么,但是如果你只设置默认statestate会像场景1一样被记住

场景一

这样即使Parent重新渲染Childstate也不会改变

const Child = () => {
  const [state] = useState(Math.random());
  return <div>{state}</div>
}

const Parent = () => {
  const [, action] = useState(true);
  return (
    <>
      <button onClick={() => action(false)}>Not Change</button>
      <Child />
    </>
  );
}

场景二

除非你把它去掉然后重新渲染Parent就算背全部Child,也就是

const Child = () => {
  const [state] = useState(Math.random());
  return <div>{state}</div>
}

const Parent = () => {
  const [state, action] = useState(true);

  useEffect(() => {
    if (!state) action(true)
  }, [state])

  return (
    <>
      <button onClick={() => action(false)}>Change</button>
      {state && <Child />}
    </>
  );
}

场景三

如果你不使用默认值state,这样每次渲染都会改变

const Child = () => {
  return <div>{Math.random()}</div>
}

const Parent = () => {
  const [, action] = useState(true);

  return (
    <>
      <button onClick={() => action(prev => !prev)}>Change</button>
      <Child />
    </>
  );
}

场景4

如果不想Child重新渲染,可以试试memo

const Child = memo(() => {
  return <div>{Math.random()}</div>
})

场景5

然而,当 Child 有 props 时,也许我们应该 invole useCallback or useMemo 以确保 props 的值或内存地址像常量一样“固定”,这样 Child 就赢了不重新渲染

(我们不必一直使用useCallbackuseMemo,在没有性能问题的情况下也无所谓 )

const Child = memo((props) => {
  return <div {...props}>{Math.random()}</div>
})

const Parent = () => {
  const [, action] = useState(true);
  const style = useMemo(() => ({}), [])
  const onOK = useCallback(() => alert(1), [])
  return (
    <>
      <button onClick={() => action(prev => !prev)}>Change</button>
      <Child className="test" style={style} onClick={onOK} />
    </>
  );
}