如何在 React 中访问孩子的状态?(反应钩子) [英] How to access child's state in React? (React Hooks)

查看:26
本文介绍了如何在 React 中访问孩子的状态?(反应钩子)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 react-hooks 访问孩子状态的最佳解决方案是什么?

我尝试了各种方法.低于我最终得到的那个.

表单(父)

export const 形式:FunctionComponent= ({ onFinish, initState }) =>{const formInputsStateRef = useRef({})const handleFinish = () =>{const 参数 = formInputsStateRef.current控制台日志(参数)完成(参数)}返回 (<div><输入initState={initState} stateRef={formInputsStateRef}/><S.Button onClick={handleFinish}>结束</S.Button>

)}

输入(子)

export const Inputs: FunctionComponent= ({ initState, stateRef }) =>{const [pool, setPool] = useState(initState.pool)const [solarPanel, setSolarPanel] = useState(initState.solarPanel)useEffect(() => {stateRef.current = { 池,solarPanel }})const handlePoolInput = () =>{setPool('新池')}const handleSolarPanelInput = () =>{setSolarPanel('新太阳能电池板')}返回 (<div><h2>{池}</h2><S.Button onClick={handlePoolInput}>更改池</S.Button><h2>{太阳能面板}</h2><S.Button onClick={handleSolarPanelInput}>更换太阳能电池板</S.Button><h2>-----</h2>

)}

它是这样工作的,但我不喜欢它在每次渲染时创建一个对象的事实.

<小时>

输入(子)

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

解决方案

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

export const Inputs: FunctionComponent= ({ initState, stateRef }) =>{const [pool, setPool] = useState(initState.pool)const [solarPanel, setSolarPanel] = useState(initState.solarPanel)useEffect(() => {stateRef.current = { 池,solarPanel }}, [池, 太阳能面板])const handlePoolInput = () =>{setPool('新池')}const handleSolarPanelInput = () =>{setSolarPanel('新太阳能电池板')}返回 (<div><h2>{池}</h2><S.Button onClick={handlePoolInput}>更改池</S.Button><h2>{太阳能面板}</h2><S.Button onClick={handleSolarPanelInput}>更换太阳能电池板</S.Button><h2>-----</h2>

)}

然而,要使用 ref 对子值进行更可控的处理,您可以使用 useImperativeHandle 钩子.

儿童

const InputsChild: FunctionComponent= ({ initState, ref }) =>{const [pool, setPool] = useState(initState.pool)const [solarPanel, setSolarPanel] = useState(initState.solarPanel)useImperativeHandle(ref, () => ({水池,太阳能板}), [池, 太阳能面板])const handlePoolInput = () =>{setPool('新池')}const handleSolarPanelInput = () =>{setSolarPanel('新太阳能电池板')}返回 (<div><h2>{池}</h2><S.Button onClick={handlePoolInput}>更改池</S.Button><h2>{太阳能面板}</h2><S.Button onClick={handleSolarPanelInput}>更换太阳能电池板</S.Button><h2>-----</h2>

)}export const Inputs = forwardRef(InputsChild);

父母

export const 形式:FunctionComponent= ({ onFinish, initState }) =>{const formInputsStateRef = useRef({})const handleFinish = () =>{const 参数 = formInputsStateRef.current控制台日志(参数)完成(参数)}返回 (<div><输入 initState={initState} ref={formInputsStateRef}/><S.Button onClick={handleFinish}>结束</S.Button>

)}

What's the best solution to get access to the child's state using react-hooks?

I've tried various approaches. Below the one that I've ended up with.

Form (Parent)


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>
  )
}

Inputs (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>
  )
}

It works that way but I don't like the fact that it creates an object on every render.


Inputs(Child)

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

解决方案

You could pass pool and solarPanel as the second argument to useEffect so that the state is updated to ref only on these values change

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>
  )
}

However to have a more controlled handle of child values using ref, you can make use of 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);

Parent

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>
  )
}
    

这篇关于如何在 React 中访问孩子的状态?(反应钩子)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆