美文网首页
React组件间通信

React组件间通信

作者: Lethe35 | 来源:发表于2019-12-27 21:01 被阅读0次

不借助redux等状态管理工具的React组件间的通信解决方法

组件通信分类

React组件间通信分为2大类,3种情况:

  • 1)有嵌套关系的
    • 父->子
    • 子->父
      这里的父通指上级组件,不一定是直属上级,可跨级
  • 2)无嵌套关系的
    • 兄弟组件间
    • 无共同上级组件的

父->子(props)

  • 方法一:父组件向子组件传递 props,子组件得到 props 后进行相应的处理。(跨多层组件的时候只需要一层一层传下去就行)


    image.png
// 父组件 Parent.js:
import React,{ PureComponent } from "react";
import Children from "./Children.js";

export default class Parent extends PureComponent{
  state = {
    title: '父组件',
  }
  outputDesc = () => {
    console.log('父组件向子组件通信,通过props传递参数或者函数');
  }
  render(){
    const { title } = this.state;
    const childProps = {
      title,
      onOutputDesc: this.outputDesc,
    }
    return(
      <Children {...childProps} />
    )
  }
}
// 子组件 Children.js:
// 界面上会显示出 【这是子组件获取到的父组件的title:父组件】
// 点击控制台会打印出 【父组件向子组件通信,通过props传递参数或者函数】
export default class Children extends PureComponent{
  render(){
    const { title, outputDesc } = this.props;
    return(
      <Fragment>
        <p>这是子组件获取到的父组件的title:{title}</p>
        <button onClick={onOutputDesc}>点击</button>
      </Fragment>
    )
  }
}

  • 方法二:通过context

使用 React提供的context API(Provider 和 Consumer)
对于方法一,如果要通信的组件间的层次结构很深,中间的每一层组件都要去传递 props,增加了复杂性,并且这些 props 并不是这些中间组件自己所需要的。
当组件层次在三层以上时建议使用context,context做的事情就是创建一个上下文对象,并且对外暴露提供者(通常在组件树中上层的位置)和消费者,在上下文之内的所有子组件,
都可以访问这个上下文环境之内的数据,并且不用通过props。可以理解为有一个集中管理state的对象,并限定了这个对象可访问的范围,在范围之内的子组件都能获取到它内部的值。

// context.js
// Provider和Consumer总是成对出现
import React from 'react'
const demoContext = React.createContext();
const demoProvider = demoContext.Provider;
const demoConsumer = demoContext.Consumer;
export demoProvider;
export demoConsumer;

// 父组件
import React from 'react'
import List from './List'
import { demoProvider } from './context'

export default class Todo extends React.PureComponent {
  state = {
      list: [],
  }
  task = React.createRef()
  handleClick = () => {
      const list = [...this.state.list, this.task.current.value];
      this.setState({ list });
      this.task.current.value = '';
  }
  deleteTask = (index) => {
    const { list } = this.state;
    list.splice(index, 1);
    this.setState({ list });
  }
  render() {
    return (
      // 在父(祖先)级组件中把要传递内容放到value里面
      <demoProvider value={{deleteTask: this.deleteTask}}>
          <input type="text" ref={this.task}/>
          <button onClick={this.handleClick}> 添加 </button>
          <List list={this.state.list} deleteTask={this.deleteTask}/>
      </demoProvider>
    );
  }
}
// 子组件
import React from 'react'
import {demoConsumer} from './context'
export default class List extends React.PureComponent{

  render() {
    const { list } = this.props
    return (
      <demoConsumer>
        // 后代组件中的组件放在Consumer里面, 内部是一个函数, 这个函数接受一个对象作为参数, 参数是Provider里面提供的值
        {
          ({ deleteTask }) => {
            return list.map((item, index) => {
              return (
                <li key={item}>
                  { item }
                  <button onClick={()=>{deleteTask(index)}}> 删除 </button>
                </li>
              )
            })
          }
        }
      </demoConsumer>
    );
  }
}

子->父(回调)

父组件将一个函数作为 props 传递给子组件,子组件调用该回调函数,向父组件通信。

// 父组件 Parent.js:
import React,{ PureComponent, Fragment } from "react";
import Children from "./Children.js";

export default class Parent extends PureComponent{
  state = {
    description: '',
  }
  handleChangeDesc = (props) => {
    this.setState({description: '子组件向父组件通信,通过回调传递参数: 在子组件中点击按钮改变父组件state中的属性})
  }
  render(){
    const { description } = this.state;
    const childProps = {
      onChangeDesc: this.handleChangeDesc,
    }
    return(
      <Fragment>
        <p>{description}</p>
        <Children {...childProps} />
      </Fragment>
    )
  }
}

// 子组件 Children.js:
// 界面上会显示出更新后的description值 【子组件向父组件通信,通过回调传递参数: 在子组件中点击按钮改变父组件state中的属性】
export default class Children extends PureComponent{
  changeParentDesc = () => {
    const { onChangeDesc } = this.props;
    onChangeDesc({description: '子组件向父组件通信,通过回调传递参数: 在子组件中点击按钮改变父组件state中的属性'});
  }
  render(){
    const { title, outputDesc } = this.props;
    return(
      <button onClick={this.changeParentDesc}>点击</button>
    )
  }
}

兄弟组件间

方法一:利用共同的上级组件作为中间人进行通信(子1->父->子2)

方法二:通过自定义发布-订阅模式的事件实现(以Node.js中events模块的EventEmitter 类为例,这个会在我的另一篇文章中细讲)

相关文章

  • React组件间通信

    不借助redux等状态管理工具的React组件间的通信解决方法 组件通信分类 React组件间通信分为2大类,3种...

  • React学习拾遗2

    组件间通信: 龟兔赛跑-React组件间通信Demo:http://js.jirengu.com/yowec/ed...

  • React Native 架构之 Redux介绍

    React 在 React 中,UI 以组件的形式来搭建,组件之间可以嵌套组合。另,React 中组件间通信的数据...

  • React父子组件间通信的实现方式

    React学习笔记之父子组件间通信的实现:今天弄清楚了父子组件间通信是怎么实现的。父组件向子组件通信是通过向子组件...

  • (1)React的开发

    1、React项目架构搭建2、JSX语法3、React组件化开发4、React组件间通信5、React中的事件6、...

  • 「React Native」Event Bus,消息总线

    (一)父子间组件通信:   一般使用props,回调函数进行通信。(二)跨组件之间通信:  (1)React Na...

  • React组件间通信

    父组件向子组件 定义组件的方法就是通过React.createClass,当我们使用组件并且给其属性的时候,这个属...

  • react组件间通信

    React 开发模式是组件化开发, 所以组件间的信息传递就尤为重要,React传递数据的方式主要有3种。 prop...

  • react组件间通信

    react中的props和state props只读,用于组件之间传递信息,这个信息包括:数据和函数 state用...

  • react组件间通信

    处理 React 组件之间的交流方式,主要取决于组件之间的关系,然而这些关系的约定人就是你。 React 组件之间...

网友评论

      本文标题:React组件间通信

      本文链接:https://www.haomeiwen.com/subject/kvqjoctx.html