- 首页
- 前端开发
- 如何在 React 中访问孩子的状态?(反应钩子)
如何在 React 中访问孩子的状态?(反应钩子)
[英] How to access child's state in React? (React Hooks)
本文介绍了如何在 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屋!