React的跨级组件通信

我们知道,react中父子组件之间的通信,父组件和子组件通信,可以通过props向子组件传递参数,子组件和父组件通信,则可以通过调用props传入的回调函数来向父组件传递参数

那么问题来了,如果是跨级组件之间的通信,如果通过props一层一层往下传,不仅逻辑会变得很不清晰,代码也会变得不好维护,这个时候,我们需要使用到react中的context来解决这个问题

首先我们来看一段代码

class Item extends Component {
    static contextTypes = {
        color: React.PropTypes.string,
    };

    render() {
        const {value} = this.props;
        return (
            
  • {value}
  • ); } } class List extends Component { static childContextTypes = { color: React.PropTypes.string, }; getChildContext() { return { color: 'red', }; } render() { const {list} = [{id:'1',text:1},{id:'1',text:2},{id:'1',text:3}] return (
      {list.map((entry, index) => ( ))}
    ); } }

    以上是一个如何通过context进行通信的示例,我们可以看到Item组件接收的color参数并不是通过props进行传递的,而是通过this.context获取的。

    要实现这个功能,首先我们需要在父组件中显式的定义静态属性childContextTypes,并在属性中声明要传入的参数的类型,同时在父组件中实现getChildContext方法,这个方法的返回值,将会传入到父组件下面的任何一个子组件的context中,这样一来,父组件的所有级别的子组件都将可以跨级别获取到父组件的参数。

    而当子组件需要使用父级及父级以上级别的组件传入的参数时,需要在子组件中显示定义静态属性contextTypes,并在属性中声明要使用的参数的类型,这样,子组件就可以在context中获取到跨级别传入的参数了。

    这种方式在react-router中得到了应用,我们可以发现,在组件中写下了以下代码之后

    static contextTypes = {
        router: React.PropTypes.object.isRequired
    }

    我们就可以使用this.context.router.push等方法,进行路由跳转了,就是这个道理。

    新的api出现

    光阴似箭岁月如梭,来到了2018年,react发布了16.3版本,提供了新的context api,看上去更加的简洁,并且用了生产者消费者模式,看看下面的示例代码

    const {Provider, Consumer} = React.createContext({
        color: 'white'
    });
    
    
    class Item extends Component {
        static contextTypes = {
            color: React.PropTypes.string,
        };
    
        render() {
            const {value} = this.props;
            return (
                
                    {context => (
                        
  • {value}
  • )}
    ); } } class List extends Component { render() { const {list} = [{id: '1', text: 1}, {id: '1', text: 2}, {id: '1', text: 3}] return (
      {list.map((entry, index) => ( ))}
    ); } }

    以上代码改写自前面的代码片段,用新的api重新实现,我们可以看到,上面的代码通过React.createContext创建出一个上下文:Context对象,然后这个Context对象又包含两个属性,一个叫Provider,另一个叫Consumer,这两个属性都是纯种的React组件。

    之后我们只需要和上面代码片段一样,在父组件中运用Provider,在子组件中运用Consumer即可,Provider中通过value属性可以向Consumer传递参数,而Consumer的子组件则是一个函数,在这个子组件中定义一个函数,Consumer会向它传递一个context,这个context来自于Provider,达到通信的目的

    和旧的api一样,这种传递参数的方式,支持跨多个级别的组件进行通信,可以用于从父组件向父组件一下的所有组件传递参数

    你可能感兴趣的:(web前端,react,react)