React Hook父组件如何获取子组件的数据/函数

 更新时间:2022年09月15日 14:28:03   作者:c_y_yuan  
这篇文章主要介绍了React Hook父组件如何获取子组件的数据/函数,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

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;
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。 

相关文章

  • React深入分析useEffect源码

    React深入分析useEffect源码

    useEffect是react v16.8新引入的特性。我们可以把useEffect hook看作是componentDidMount、componentDidUpdate、componentWillUnmounrt三个函数的组合
    2022-11-11
  • react.js使用webpack搭配环境的入门教程

    react.js使用webpack搭配环境的入门教程

    本文主要介绍了react 使用webpack搭配环境的入门教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
    2017-08-08
  • react中如何使用局部样式

    react中如何使用局部样式

    这篇文章主要介绍了react中如何使用局部样式问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-10-10
  • react纯函数组件setState更新页面不刷新的解决

    react纯函数组件setState更新页面不刷新的解决

    在开发过程中,经常遇到组件数据无法更新,本文主要介绍了react纯函数组件setState更新页面不刷新的解决,感兴趣的可以了解一下
    2021-06-06
  • react实现移动端下拉菜单的示例代码

    react实现移动端下拉菜单的示例代码

    这篇文章主要介绍了react实现移动端下拉菜单的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-01-01
  • React前端解链表数据结构示例详解

    React前端解链表数据结构示例详解

    这篇文章主要为大家介绍了React前端解链表数据结构示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-10-10
  • React操作DOM之forwardRef问题

    React操作DOM之forwardRef问题

    这篇文章主要介绍了React操作DOM之forwardRef问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • ES6下React组件的写法示例代码

    ES6下React组件的写法示例代码

    这篇文章主要给大家介绍了在ES6下React组件的写法,其中包括定义React组件、声明prop类型与默认prop、设置初始state、自动绑定,文中分别给出了详细的示例代码供大家参考学习,对大家具有一定的参考学习价值,需要的朋友们下面来一起看看吧。
    2017-05-05
  • React虚拟列表的实现

    React虚拟列表的实现

    在开发过程中,总是遇到很多列表的显示。当上数量级别的列表渲染于浏览器,终会导致浏览器的性能下降,你可以选择其他方式避免,本文就介绍了虚拟列表来解决这个问题
    2021-05-05
  • React组件设计过程之仿抖音订单组件

    React组件设计过程之仿抖音订单组件

    这篇文章主要介绍了React组件设计过程之仿抖音订单组件的实现示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-07-07

最新评论