網站首頁 編程語言 正文
React Hook父組件獲取子組件數據/函數
我們知道在react中,常用props實現子組件數據到父組件的傳遞,但是父組件調用子組件的功能卻不常用。
文檔上說ref其實不是最佳的選擇,但是想著偷懶不學redux,在網上找了很多教程,要不就是hook的講的太少,要不就是父子組件傻傻分不清,于是只好再啃了一下文檔,就學了一下其它hook的api。
在這里我們需要用到useImperativeHandle這個api,其函數形式為
useImperativeHandle(ref, createHandle, [deps])
其實這個api也是ref的一種形式,但是相當于做了一定的優化,可以選擇讓子組件只暴露一定的api給父組件,根據在文檔和其他博客上給出的方法
一共有兩大步驟:
- 1.將ref傳遞到子組件中
- 2.需要使用forwardRef對子組件進行包裝
子組件MyWorldMap
?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);
兩種方法都是可以的
父組件MyTrip
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()調用函數了
React Hook父組件提交子組件form
父組件
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;
}
原文鏈接:https://www.cnblogs.com/yuyuan-bb/p/11478837.html
相關推薦
- 2022-08-13 Spring Boot中Lombok的使用
- 2022-05-17 Git分支管理策略_其它綜合
- 2022-05-03 C#面向對象設計原則之里氏替換原則_C#教程
- 2022-07-28 Python知識點詳解之正則表達式語法_python
- 2022-11-23 淺析Golang切片截取功能與C++的vector區別_Golang
- 2023-01-20 Flask框架使用異常捕獲問題_python
- 2023-11-13 【云原生】docker-compose安裝,解決Warning: the “docker“ comm
- 2022-03-15 this.$cookie.set(‘token‘, data.token) token賦值失效
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支