最近我正在研究React并从父级调用子级函数,但是当我在ref上调用current时,它使我不确定。
实际上,引用很适合以前的Parent组件,甚至也可以调用useImperativeHandle
函数,但是当使用useImperativeHandle
调用另一个子ref时,它在当前状态下未定义。
export const ZoneMapView = forwardRef((props,ref) => {
const draw_map=useRef();
useImperativeHandle(ref, () => ({
call: ()=> {
alert(draw_map.current);
}
}));
return (
<div className="map-view">
<BaseMap ref={draw_map}/>
</div>
);
});
正在从父组件中调用 Call方法,但随后在alert(draw_map.current)
上未定义。如何访问子功能?希望获得帮助
答案 0 :(得分:3)
我对useRef
和useImperativeHandle
的教育还处于初期,但这是我对它的理解。
很难从问题中提供的代码中看出如何设置组件,但是听起来您想从嵌套的子组件中调用方法。表示您有一个
Parent
> Middle
> Child
组件结构,并希望从Child
中的Parent
调用方法。
为此,您可以将ref
通过Middle
组件传递到Child
,从而允许在Child
中调用Parent
方法。
但是,似乎可以用一种更简单,更容易理解的方式来处理它-例如,使用Redux或将函数作为道具传递给孩子。没有看到完整的代码,很难提出建议。
这是一个简化的演示:
const Child = React.forwardRef((props, ref) => {
const buttonRef = React.useRef();
const handleClick = (event) => {
console.log('button click')
}
const childStyle = {
margin: 20
}
React.useImperativeHandle(ref, () => ({
click: () => {
buttonRef.current.click()
}
}))
return (
<button ref={buttonRef} style={childStyle} onClick={handleClick}>Child Component</button>
)
})
const Middle = ({childRef}) => {
const middleStyle = {
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
padding: 20,
backgroundColor: 'darkgray'
}
return (
<div style={middleStyle}>
Middle Component
<Child ref={childRef} />
</div>
)
}
const Parent = () => {
const childRef = React.useRef()
const parentStyle = {
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
textAlign: 'center',
backgroundColor: 'lightgray',
padding: 20
}
const handleMouseEnter = () => {
/*
* CALL A METHOD FROM THE CHILD
*/
childRef.current.click()
}
return (
<div style={parentStyle} onMouseEnter={handleMouseEnter}>
<p>
Parent Component<br />
onMouseEnter of this gray area the onClick of the button will be called
</p>
<Middle childRef={childRef} />
</div>
)
}
ReactDOM.render(<Parent />, document.getElementById("app"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
<div id="app"></div>