React-父子组件通信

170 阅读2分钟

技术栈:react17+typescript4.6+creat-react-app

父组件app.tsx

import type { Son1Ref } from './pages/Son1'
import { useRef } from 'react'
import Son0 from './pages/Son0';
import Son1 from './pages/Son1';
import Son2 from './pages/Son2';

const App = () => {
  const Son1Ref = useRef<Son1Ref>() as React.MutableRefObject<Son1Ref>;
  // 父组件调用子组件的方法
  const parentClick = () => Son1Ref.current.handleSon1() ;
  return (
    <div>
      <div>
        <button onClick={parentClick}>父组件调用子组件的方法</button>
      </div>
      <div>
        <div>父组件向子组件Son0传参</div>
        <Son0 parentNum={333} parentEvent={() => console.log('2222')}></Son0>
        <div>父组件调用子组件Son1的方法,执行子组件的方法</div>
        <Son1 ref={Son1Ref}></Son1>
        <div>子组件Son2调用父组件的方法,向父组件传参</div>
        <Son2 onSelect={text => {console.log(text)}}></Son2>
      </div>
    </div>
  );
}

export default App;

一.父组件向子组件传递数据-通过props-Son0

(1)在子组件Son0定义要传递那些参数

(2)在父组件App.tsx通过Prop的方式传参

import React from 'react'; //Son0

interface Propstype {
  parentNum?: number; //可选,默认值为1
  parentEvent: () => void; //必选
}

const Son2: React.FC<Propstype> = ({ parentNum = 1, parentEvent }) => {
  return <div onClick={parentEvent}>{parentNum}</div>
}

export default Son2

二.子组件向父组件传递数据-通过自定义回调函数的方式-Son2

(1)子组件Son2定义onclick事件,将需要传递的Son2内的数据number,通过函数的方式传递给父组件的自定义方法onSelect.

(2)定义Propstype

(3)在父组件中,定义onSelect={text => {console.log(text)}},获取并对子组件传递来的数据进行相应的操作。

import React from 'react';

interface Propstype {
  onSelect: (text: string) => void; // 向父组件返回子组件的数据,必选
}

const Son2: React.FC<Propstype> = ({ onSelect }) => {
  const handleParent = (number: string) => onSelect(number)
  return <div onClick={() => handleParent('Son2-number')}>Son2</div>
}

export default Son2

三.父组件调用子组件的方法-通过useRef-Son1

(1)子组件引入import {useImperativeHandle, forwardRef } from 'react';

(2)用forwardRef包裹子组件

(3)定义需要抛出的方法handleSon1,并使用useImperativeHandle将其抛出(useImperativeHandle(ref, () => ({ handleSon1 }));)使得handelSon1能够被外部访问

(4)父组件引入useRef,import { useRef } from 'react'和类型useRef,定义点击事件parentClick

import {useImperativeHandle, forwardRef } from 'react';

// prop
interface PropsType {
  number?: number
}

export type Son1Ref = {
  handleSon1: () => void;
};

const Son1 = forwardRef<Son1Ref, PropsType>(
  ({number}, ref) => {
  // 子组件里的方法
  const handleSon1 = () => console.log('handleSon1');
  //用useImperativeHandle暴露一些外部ref能访问的属性
  useImperativeHandle(ref, () => ({ handleSon1 }));
  return <div>Son1</div>
})

export default Son1