首页 > 其他分享 >React组件通信

React组件通信

时间:2022-10-18 16:01:29浏览次数:62  
标签:price Component 通信 React state context props 组件

react因为组件化,使得组件间通信十分的重要。本文就来简单介绍一些常见的react组件间传递的内容。
我将归纳为以下几种关系来详述:父组件与子组件之间子组件与父组件之间发布者与订阅者模式(context)兄弟组件间,redux也是一种组件管理的方法,但是redux状态管理的内容比较多,这里只做简单介绍,之后再另开一篇详述。

父组件向子组件通信

react的数据流是单向的,最常见的就是通过props由父组件向子组件传值。

示例(关键部分有注释):

我们做一个简单的选择商品,然后改变价格的事例。

父组件:
父组件就是两个按钮,用来切换商品的价格,其中引用了子组件。

class Parents extends Component {
   //构造函数
  constructor() {
    super();
    // 设置state
    this.state = {
      price: 0
    };
  }

clickGoods(e) {
    //更新state
    this.setState({
        price: e
    });
}


  // 渲染
  render() {
    let { price } = this.state;
    return (
      <div>
        <button onClick={this.clickGoods1.bind(this)}>goods1</button>
        <button onClick={this.clickGoods2.bind(this)}>goods2</button>
        // 父组件中        <Child price={price} />
      </div>
    );
  }
}

子组件:
子组件中使用props属性接收传递来的数据。

class Child extends Component {
  render() {
  {/*这里从props中拿到*/}
    return <div> price: {this.props.price} </div>;
  }
}

子组件向父组件通信

接下来我们反过来,让子组件向父组件通信。 子组件向父组件通信的基本思路是,父组件向子组件传一个函数,然后通过这个函数的回调,拿到子组件传过来的值。下面是例子,正好和上面是反的,父组件用来显示价格,子组件显示两个按钮,子组件把价格传递给父组件。

示例(关键部分有注释):

父组件

class Parents extends Component {
  constructor() {
    super();
    this.state = {
      price: 0
    };
  }

  getItemPrice(e) {
    this.setState({
      price: e
    });
  }

  render() {
    return (
      <div>
        <div>price: {this.state.price}</div>
        {/* 向子组件中传入一个函数  */}
        <Child getPrice={this.getItemPrice.bind(this)} />
      </div>
    );
  }
}

子组件

class Child extends Component {
  clickGoods(e) {
    // 在此函数中传入值
    this.props.getPrice(e);
  }

  render() {
    return (
      <div>
        <button onClick={this.clickGoods.bind(this, 100)}>goods1</button>
        <button onClick={this.clickGoods.bind(this, 1000)}>goods2</button>
      </div>
    );
  }
}

发布者与订阅者模式(context)

React 的props都是由父组件传递给子组件的,一旦遇到孙组件,就需要一层层的传递下去。而context提供了一种组件之间通讯的新的方式(16.3版本之后),可以共享一些数据,其它的组件都能从context中读取数据(类似于有个数据源,组件可以订阅这个数据源)。

使用方法

React.createContext()方法

我们可以使用createContext来创建一个context,它可以接收一个变量或者对象做为参数(当对象为参数的时候,react使用object.is()去比较,有些影响性能)。这个传入的值做为context的默认值

 const PriceContext = React.createContext('price')

这样就创建了一个Context

Provider组件

Provider就是用来创建数据源的。它是给所有的子组件提供数据源的跟组件。它接受一个value作为props,用来传递值,它会改变context的默认值。一个provider可以包含多个Consumer组件。如果Provider组件嵌套的话,

<PriceContext.Provider value={100}>
</PriceContext.Provider>

Consumer组件

Consumer表示接受数据的组件,它接受一个函数做为子元素。这个函数会接收context传递的值,返回一个react的组件。Consumer组件必须包含在Provider里面。

<PriceContext.Consumer>
    { /*这里是一个函数*/ }
    {
        price => <div>price:{price}</div>
    }
</PriceContext.Consumer>

示例

在这部分我们尝试一下从父组件直接传递到孙组件,不通过子组件(直接从A组件传值到C组件,不经过B组件)。

参考React实战视频讲解:进入学习

// 创建Context
const PriceContext = React.createContext('price')
// A组件中
class ClassA extends Component {
  constructor(){
    super()
    this.state={
      price:0
    }
  }
  // 点击按钮事件
  clickGoods(e) {
    this.setState({
      price:e
    })
  }
  render(){
    const { price } = this.state
    return(
      // Provider
      // 把state里price转到Provider的value中
    <PriceContext.Provider value={price}>
        <button onClick={this.clickGoods.bind(this, 100)}>goods1</button>
        <button onClick={this.clickGoods.bind(this, 1000)}>goods2</button>
        <ClassB />
    </PriceContext.Provider>  
    )
  }
}
// 组件B
class ClassB extends Component {
  // 组件B中只是引用了ClassC,没有进行传值的操作
  render(){
    return(
      <div><span>price:</span><span><ClassC /></span></div>
    )
  }
}
// 组件C
class ClassC extends Component {
  render(){    
    return(
      // Consumer,注意Consumer的下面要包含一个函数
      <PriceContext.Consumer>
        {
          price=><span>{price}</span>
        }
      </PriceContext.Consumer>
    )
  }
}

context的总结与理解

一个react app是由很多react组件组成的,有的组件之间是有嵌套关系的,可以形成一条“组件链”。Context可以当做组件的“作用域”[3]。一个根组件,它定义了一个context,它的组件链上的组件都可以访问到provider中定义的变量或对象,如下图所示,这就比较像‘作用域’的概念。context在一些简单的场景下可以替代部分redux的功能。

兄弟组件间通信

兄弟间组件通信,一般的思路就是找一个相同的父组件,这时候既可以用props传递数据,也可以用context的方式来传递数据。
当然也可以用一些全局的机制去实现通信,比如redux等。

小结

本文主要介绍了3种通信的关系父组件与子组件之间子组件与父组件之间发布者与订阅者模式(context),简述了兄弟组件间的通信。主要是介绍两种方式,利用props属性和Context。也介绍了一些context的理解。

标签:price,Component,通信,React,state,context,props,组件
From: https://www.cnblogs.com/xiaofeng123aa/p/16802858.html

相关文章

  • 一段探索React自建内部构造的旅程
    一段探索React自建内部构造的旅程在先前的文章里我们涵盖了​​React基本原理​​​和​​如何构建更加复杂的交互组件​​。此篇文章我们将会继续探索React组件的特性,特......
  • 细说React组件性能优化
    React组件性能优化最佳实践React组件性能优化的核心是减少渲染真实DOM节点的频率,减少VirtualDOM比对的频率。如果子组件未发生数据改变不渲染子组件。组件卸载前......
  • 在Vue项目中使用Echarts : Echarts中的常用组件--堆叠面积图
    一、安装并全局引入1、通过npm获取echartsnpminstallecharts--save2、在main.js中添加下面两行代码在main.js中引入5.0以下版本 importechartsfrom'echar......
  • React组件设计模式-纯组件,函数组件,高阶组件
    一、组件(1)函数组件如果你想写的组件只包含一个render方法,并且不包含state,那么使用函数组件就会更简单。我们不需要定义一个继承于React.Component的类,我们可以定......
  • 升级到React-Router-v6
    前言近期完成了公司新项目的开发,相关的技术栈都用到了最新版本,reactrouter也使用了v6的版本,所以借这个机会自己再梳理下reactrouterv5与v6的区别,以及v6一些新......
  • 详解React的Transition工作原理原理
    Transition使用姿势Transition是react18引入的新概念,用来区分紧急和非紧急的更新。紧急的更新,指的是一些直接的用户交互,如输入、点击等;非紧急的更新,指的是UI界面......
  • react typesctipt
    React.FC是函数式组件,是在TypeScript使用的一个泛型,FC就是FunctionComponent的缩写,事实上React.FC可以写成React.FunctionComponent:React.FC包含了PropsWithChildren......
  • ImageList组件
    ImageList组件只有属性,没有事件常用属性:Images,ImageSizeImages的方法:Add(Image/Icon)Add(string,Image/Icon)Contains(Image/Icon)IndexOf(Image/Icon)Remove(Image......
  • react-Suspense工作原理分析
    Suspense基本应用Suspense目前在react中一般配合lazy使用,当有一些组件需要动态加载(例如各种插件)时可以利用lazy方法来完成。其中lazy接受类型为Promise<()=......
  • C#如何弹出输入框 <弹出“添加引用”的窗口,找到名称为Microsoft.VisualBasic的组
    1、菜单栏,选择【项目】;然后在弹出的菜单中选择【添加引用】 2、弹出“添加引用”的窗口,找到名称为Microsoft.VisualBasic的组件,选择它并点击【确定】 3、使用命名空......