[英]How to access child's state in React? (React Hooks)
What's the best solution to get access to the child's state using react-hooks?使用 react-hooks 访问孩子状态的最佳解决方案是什么?
I've tried various approaches.我尝试了各种方法。 Below the one that I've ended up with.在我最终得到的那个下面。
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>
)
}
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您可以将 pool 和 solarPanel 作为 useEffect 的第二个参数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>
)
}
However to have a more controlled handle of child values using ref, you can make use of useImperativeHandle
hook.但是,要使用 ref 对子值进行更可控的处理,您可以使用useImperativeHandle
钩子。
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>
)
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.