记录React中父组件使用调用子组件方法

日常开发中组件之间的通信是比较经常需要使用到的一点,react的组件数据流方式是从父组件传到子组件,如果子组件需要用到父组件的方法,可以在父组件之间通过props传递,子组件进行调用。但是在业务上有时候无法避免需要用到子组件调用父组件的方法的场景

子组件访问父组件的方法

子组件要访问父组件的方法就比较简单,可以直接通过props来传递父组件的方法,子组件通过props向上调用的方式来访问父组件的函数,直接调用,下面是一些举例的代码。

js 复制代码
const ParentComponent = () => {
	const handleState = (value) => {
	}
	return (
		<ChildComponent getState={handleState}/>
	)
}

const ChildComponent = (props) => {
	const callMethod = () => {
		props.getState('123')
	}
	return (
		<Button onClick={callMethod}>调用父组件方法</Button>
	)
}

父组件访问子组件

用下面的方法来获取子组件的方法,创建一个ref,和vue访问子组件的方式类似,都是通过ref的方法

js 复制代码
import React, { Component } from 'react';
const inputRef = useRef<Input | null>(null);
<div
  className={classNames(className, styles.headerSearch)}
  onClick={() => {
    setSearchMode(true);
    if (searchMode && inputRef.current) {
      inputRef.current.focus();
    }
  }}
  onTransitionEnd={({ propertyName }) => {
    if (propertyName === 'width' && !searchMode) {
      if (onVisibleChange) {
        onVisibleChange(searchMode);
      }
    }
  }}
>
<Input
  size="small"
  ref={inputRef}
  defaultValue={defaultValue}
  aria-label={placeholder}
  placeholder={placeholder}
  onKeyDown={(e) => {
    if (e.key === 'Enter') {
      if (restProps.onSearch) {
        restProps.onSearch(value);
      }
    }
  }}
  onBlur={() => {
    setSearchMode(false);
  }}
/>

但是上面的方法尝试过后会发现可能存在inputRef.current等于undefined的情况,用起来不是很方便,所以建议尝试下面的方法

useImperativeHandle

useImperativeHandle 是 React 中的一个自定义 Hook,它允许函数式组件与父组件之间的通信。通常情况下,React 的数据流是自上而下的,但有时候需要从子组件向父组件传递数据或方法。useImperativeHandle 就是一个比较方便实现的方法

javascript 复制代码
javascriptCopy code
import React, { useRef, useImperativeHandle, forwardRef } from 'react';

// 子组件
const ChildComponent = forwardRef((props, ref) => {
  const internalRef = useRef();

  // 在子组件中定义需要暴露给父组件的方法或数据
  useImperativeHandle(ref, () => ({
    someFunction: () => {
      // 这个函数可以在父组件中被调用
      console.log('Function from ChildComponent called');
    },
    someData: 'Data from ChildComponent',
  }));

  return (
    <div>
      {/* 子组件的内容 */}
    </div>
  );
});

// 父组件
function ParentComponent() {
  const childRef = useRef();

  const handleButtonClick = () => {
    // 在父组件中调用子组件暴露的函数
    childRef.current.someFunction();
  }

  return (
    <div>
      <ChildComponent ref={childRef} />
      <button onClick={handleButtonClick}>Call ChildComponent Function</button>
    </div>
  );
}

在上面的示例中,useImperativeHandle 用于子组件 ChildComponent,并通过 forwardRef 使得父组件能够访问 childRef.current,调用子组件的函数。父组件可以在需要时通过 childRef.current 访问子组件的暴露接口,调用函数或访问数据。

总结

其实react开发中并不赞成去用ref来访问子组件的方法,因为使用ref需要父组件知道子组件内部的解构和方法命名,这样就无法遵从解耦的原则,组件会变得更加的难以重用和维护,并且react推荐组件的独立性和封装性,只通过props来进行通信,直接访问子组件会破坏封装性,导致需要配合父组件来修改子组件

并且组件整个替换或者需要修改内部逻辑的时候,可能需要同时修改子组件和父组件的方法,会大大的增加在开发中的维护复杂度,在开发中应该尽量避免用父组件来访问子组件的方法

如果觉得有趣或有收获,请关注我的更新,给个喜欢和分享。您的支持是我写作的最大动力!

往期好文推荐

相关推荐
浮华似水15 分钟前
简洁之道 - React Hook Form
前端
2401_857622662 小时前
SpringBoot框架下校园资料库的构建与优化
spring boot·后端·php
正小安2 小时前
如何在微信小程序中实现分包加载和预下载
前端·微信小程序·小程序
2402_857589362 小时前
“衣依”服装销售平台:Spring Boot框架的设计与实现
java·spring boot·后端
哎呦没3 小时前
大学生就业招聘:Spring Boot系统的架构分析
java·spring boot·后端
小飞猪Jay4 小时前
C++面试速通宝典——13
jvm·c++·面试
_.Switch4 小时前
Python Web 应用中的 API 网关集成与优化
开发语言·前端·后端·python·架构·log4j
一路向前的月光4 小时前
Vue2中的监听和计算属性的区别
前端·javascript·vue.js
长路 ㅤ   4 小时前
vite学习教程06、vite.config.js配置
前端·vite配置·端口设置·本地开发
长路 ㅤ   4 小时前
vue-live2d看板娘集成方案设计使用教程
前端·javascript·vue.js·live2d