React组件通讯

118 阅读3分钟

react组件之间通讯方式其实和vue组件之间的通信类似,可以对比学习。

可以传递任意类型的数据:比如基本类型、引用类型、Map、函数、react元素(组件)等。

1、父子组件通信

  • 在父组件中通过给子组件标签添加属性
  • 在子组件中通过props接收数据

这里只列举了传递字符串、函数、react元素,其他类型可以自己试,方式都是一样。

// 父组件中
class Parent extends React.Component {
  state = {
    firstName: '百',
  };
  render() {
    return (
      <div className="bg-0069ff pa-4">
        <div>父组件</div>
        {/* 父组件中通过给子组件标签添加属性传值 */}
        {/* 注意这里的属性名可以是任意的合法名称,在子组件中接收数据的名称保持一致 */}
        <Child
          firstName={this.state.firstName}
          fn={() => console.log('传一个函数')}
          ele={<p>传一个react元素</p>}
        ></Child>
      </div>
    );
  }
}

子组件是函数组件

  • 通过形参 props 接收传过来的数据,是一个对象
// 子组件是函数组件
function Child(props) { // 形参 props 接收
  // 调用传过来的函数
  props.fn()
  return (
    <div className="bg-00a364">
      <div>函数子组件</div>
      {/* 这里的属性名称要和父组件中传递的属性名一致 */}
      <div>接收父组件传过来的值: {props.firstName}家姓</div>
      {/* 将传过来的元素渲染到子组件中 */}
      {props.ele}
    </div>
  );
}

子组件是类组件

  • 直接通过 this.props.xxx 访问数据
class Child1 extends React.Component {
  // 如果函数组件中有 constructor 构造函数,要将props作为参数传递给构造函数和 super ,否则在里面访问不到this.props
  // 注意如果不传,并不会影响在 其他地方,比如render中通过 this.props 访问数据

  // 错误
  // constructor() {
  //   super()
  //   console.log(this.props) // undefined
  // }

  // 正确
  constructor(props) {
    super(props)
    console.log(props)
    console.log(this.props)
  }
  render() {
    return (
      <div className="bg-64B5F6">
        <div>类子组件</div>
        <p>接收父组件传过来的值:{this.props.firstName}家姓</p>
        {this.props.ele}
      </div>
    );
  }
}

Snipaste_2022-10-07_13-47-49.jpg

2、子父组件通信

子组件向父组件传递数据需要用回调函数的方式,通过回调函数的参数将数据传递给父组件

  • 父组件给子组件传递一个函数
  • 子组件调用函数,并将要传递的数据作为回调函数的参数
class Parent extends React.Component {
  state = {
    childData: ''
  }
  getChildData = (data) => {
    console.log('接收子组件传过来的数据', data)
    this.setState({
      childData: data
    })
  }
  render() {
    return (
      <div className="bg-0069ff pa-4">
        <div>父组件</div>
        <div>接收到了子组件传递的数据: {this.state.childData}</div>
        <Child fn={this.getChildData}></Child>
      </div>
    );
  }
}


function  Child (props) {
  function handleClick () {
    // 调用父组件传过来的函数,并传递参数
    props.fn('这是给父组件的一些data')
  }
  return (
    <div className="bg-00a364">
      <div>子组件</div>
      <button onClick={handleClick}>点我, 发送数据给父组件</button>
    </div>
  );
}

3、兄弟组件通信

这里主要说的是两个组件在同一个父组件中,两个子组件处于平级的情况,其他情形如果使用状态提示比较繁琐时,建议通过 context 或者 事件对象(events)的方式。

兄弟组件通信是使用 状态提升 的方法,将要传递的数据提升到最近的共同的父组件中,然后进行传递和修改操作。

// 共同的父组件
class Counter extends React.Component {
  state = {
    count: 1,
  };

  addNum = () => {
    this.setState({
      count: this.state.count + 1,
    });
  };

  render() {
    return (
      <div>
        <div>计数器</div>
        <Child1 count={this.state.count}></Child1>
        <Child2 fn={this.addNum}></Child2>
      </div>
    );
  }
}

// 兄弟组件1
function Child1(props) {
  return <div>当前值是: {props.count}</div>;
}

// 兄弟组件2 中的按钮被点击之后,需要更新组件1中的当前值
function Child2(props) {
  return <button onClick={() => props.fn()}>+1</button>;
}