关于react.js:React组件通信

1次阅读

共计 3318 个字符,预计需要花费 9 分钟才能阅读完成。

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 的了解。

正文完
 0