目录React Hook父组件获取子组件数据/函数子组件MyWorldMap父组件MyTripReact Hook父组件提交子组件fORM父组件子组件React Hook父组件获取子
我们知道在react中,常用props实现子组件数据到父组件的传递,但是父组件调用子组件的功能却不常用。
文档上说ref其实不是最佳的选择,但是想着偷懒不学redux,在网上找了很多教程,要不就是hook的讲的太少,要不就是父子组件傻傻分不清,于是只好再啃了一下文档,就学了一下其它hook的api。
在这里我们需要用到useImperativeHandle这个api,其函数形式为
useImperativeHandle(ref, createHandle, [deps])
其实这个api也是ref的一种形式,但是相当于做了一定的优化,可以选择让子组件只暴露一定的api给父组件,根据在文档和其他博客上给出的方法
一共有两大步骤:
const mapRef = useRef(null);
useImperativeHandle(ref, () => {
return {
//clickSwitch是子组件暴露的函数
clickSwitch() {
if(type == 1){
initChinaMap();
setType(2);
}else{
initWordMap();
setType(1);
}
}
}
})
//你的return内容,注意ref
return(
<React.Fragment>
<div id={"myWorldMap"} style={{ width: "800px", height: "400px" }} ref={mapRef}></div>
</React.Fragment>
)
}
//最后要配合forwardRef
MyWorldMap = forwardRef(MyWorldMap);
export default MyWorldMap;
注:ref是子组件声明的时候传进来的,也就是
function MyWorldMap (props,ref){
//..你的代码
}
//export...
其实官方文档给出来的例子是:
function FancyInput(props, ref) {
const inputRef = useRef();
useImperativeHandle(ref, () => ({
focus: () => {
inputRef.current.focus();
}
}));
return <input ref={inputRef} ... />;
}
FancyInput = forwardRef(FancyInput);
两种方法都是可以的
const myWordMapRef = useRef();
return(
//省略一些代码,注意ref
<MyWorldMap proData = { myMapData} handleMapClick = {handleMapClick.bind(this)} ref={myWordMapRef}>
</MyWorldMap>
<div className={styles["mapButton-wrap"]}>
<ButtonGroup>
<Button onClick={() => myWordMapRef.current.clickSwitch()}>Switch</Button>
<Button onClick={()=>clickAll() }>All</Button>
</ButtonGroup>
</div>
)
现在你就可以在父组件里面通过myWordMapRef.current.clickSwitch()调用函数了
import React, { useState, useEffect, useRef } from 'react';
import { Button } from 'antd';
import EditClassA from './EditClassA';
export default (): React.Reactnode => {
const [isEdit,setIsEdit] = useState<boolean>(false);
const editClassARef = useRef();
const handleSave = () => {
// 调用子组件的方法
editClassARef.current.changeVal();
}
return (
<div>
{!isEdit?(
<Button style={{marginRight:20}} onClick={()=>setIsEdit(!isEdit)}>编辑</Button>
):(
<Button style={{marginRight:20}} onClick={handleSave}>保存</Button>
)}
</div>
<EditClassA isEdit={isEdit} setIsEdit={setIsEdit} ref={editClassARef}/>
)
}
import React, { useImperativeHandle, forwardRef } from 'react';
import { Form , Input } from 'antd';
import style from '@/pages/BackEnd/style.less';
const EditClassA = forwardRef((props, ref) => {
// props 里面有父组件的值和方法
const [form] = Form.useForm();
useImperativeHandle(ref, () => ({
changeVal: () => {
form
.validateFields()
.then( values => {
// 调用父组件方法,设置父组件的值
props.setIsEdit(!props.isEdit)
})
.catch(errorInfo => {
return false
})
}
}));
return (
<Form form={form} name="basic" colon={false} >
<Form.Item
label="总部名称"
name="name"
initialValue="总部"
rules={[{required: true,message: '请输入总部名称',}]}>
<Input className={props.isEdit?'':style.disabledInput} placeholder="请输入" disabled={!props.isEdit}/>
</Form.Item>
</Form>
);
})
export default EditClassA
.disabledInput[disabled]{
color: rgba(0, 0, 0, 0.85);
background-color: transparent;
cursor: default;
border: unset;
border-bottom: 1px solid #333;
}
以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。
--结束END--
本文标题: ReactHook父组件如何获取子组件的数据/函数
本文链接: https://lsjlt.com/news/167634.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-01-12
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0