javascript - 如何在 React 中访问 child 的状态? ( react 钩子(Hook))

标签 javascript reactjs react-hooks

使用 react-hooks 获取子状态的最佳解决方案是什么?

我尝试过各种方法。在我最后得到的那个下面。

表单(父级)


export const Form: FunctionComponent<IProps> = ({ onFinish, initState }) => {
  const formInputsStateRef = useRef({})

  const handleFinish = () => {
    const params = formInputsStateRef.current
    console.log(params)
    onFinish(params)
  }

  return (
    <div>
      <Inputs initState={initState} stateRef={formInputsStateRef}  />
      <S.Button onClick={handleFinish}>
        Finish
      </S.Button>
    </div>
  )
}

输入( child )

export const Inputs: FunctionComponent<IProps> = ({ initState, stateRef }) => {
  const [pool, setPool] = useState(initState.pool)
  const [solarPanel, setSolarPanel] = useState(initState.solarPanel)

  useEffect(() => {
    stateRef.current = { pool, solarPanel }
  })

  const handlePoolInput = () => {
    setPool('new pool')
  }

  const handleSolarPanelInput = () => {
    setSolarPanel('new solar panel')
  }

  return (
    <div>
      <h2>{pool}</h2>
      <S.Button onClick={handlePoolInput}>Change pool</S.Button>
      <h2>{solarPanel}</h2>
      <S.Button onClick={handleSolarPanelInput}>Change solar panel</S.Button>
      <h2>-----</h2>
    </div>
  )
}

它以这种方式工作,但我不喜欢它在每次渲染时创建一个对象这一事实。


输入( child )

useEffect(() => {
    stateRef.current = { pool, solarPanel }
})

最佳答案

您可以将 pool 和 solarPanel 作为第二个参数传递给 useEffect,以便仅在这些值发生变化时更新状态以引用

export const Inputs: FunctionComponent<IProps> = ({ initState, stateRef }) => {
  const [pool, setPool] = useState(initState.pool)
  const [solarPanel, setSolarPanel] = useState(initState.solarPanel)

  useEffect(() => {
    stateRef.current = { pool, solarPanel }
  }, [pool, solarPanel])

  const handlePoolInput = () => {
    setPool('new pool')
  }

  const handleSolarPanelInput = () => {
    setSolarPanel('new solar panel')
  }

  return (
    <div>
      <h2>{pool}</h2>
      <S.Button onClick={handlePoolInput}>Change pool</S.Button>
      <h2>{solarPanel}</h2>
      <S.Button onClick={handleSolarPanelInput}>Change solar panel</S.Button>
      <h2>-----</h2>
    </div>
  )
}

但是,要使用 ref 更好地控制子值的句柄,您可以使用 useImperativeHandle Hook 。

child

const InputsChild: FunctionComponent<IProps> = ({ initState, ref }) => {
  const [pool, setPool] = useState(initState.pool)
  const [solarPanel, setSolarPanel] = useState(initState.solarPanel)

  useImperativeHandle(ref, () => ({
    pool,
    solarPanel
  }), [pool, solarPanel])

  const handlePoolInput = () => {
    setPool('new pool')
  }

  const handleSolarPanelInput = () => {
    setSolarPanel('new solar panel')
  }

  return (
    <div>
      <h2>{pool}</h2>
      <S.Button onClick={handlePoolInput}>Change pool</S.Button>
      <h2>{solarPanel}</h2>
      <S.Button onClick={handleSolarPanelInput}>Change solar panel</S.Button>
      <h2>-----</h2>
    </div>
  )
}

export const Inputs = forwardRef(InputsChild);

父级

export const Form: FunctionComponent<IProps> = ({ onFinish, initState }) => {
  const formInputsStateRef = useRef({})

  const handleFinish = () => {
    const params = formInputsStateRef.current
    console.log(params)
    onFinish(params)
  }

  return (
    <div>
      <Inputs initState={initState} ref={formInputsStateRef}  />
      <S.Button onClick={handleFinish}>
        Finish
      </S.Button>
    </div>
  )
}
    

关于javascript - 如何在 React 中访问 child 的状态? ( react 钩子(Hook)),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54702565/

相关文章:

javascript - javascript 中的反跳实时搜索不执行闭包

javascript - 为什么组件重新渲染后输入元素没有重新获得焦点?

javascript - 通过 ReactJS 使用 MaterializeCSS 显示 HTML 元素

reactjs - 如何在类组件中使用 react-redux useSelector?

javascript - JavaScript 中的 2 级继承

javascript - Bootstrap DateTimePicker 和 jQuery 问题

javascript - 如何清除过滤器 - AngularJS

android - 如何在 React Native 的抽屉导航中使用 ContextAPI?

javascript - 选择/打开新下拉菜单时自动关闭下拉菜单( react )

reactjs - 如何使用 React Hooks 将焦点集中在下一个渲染上