美文网首页web 杂谈React Native开发经验集Web前端之路
React 组件件通信2——非父子组件间通信

React 组件件通信2——非父子组件间通信

作者: 高少辉_骚辉 | 来源:发表于2017-06-02 15:32 被阅读633次

    孙辈级通信

    当需要让子组件跨级访问信息时候,我们可以通过之前那篇React 组件之间的通信1——之父子之间的通信那样向更高级别的组件,层层传递props,但此时的代码不仅显得不那么优雅,甚至有些冗余。在 React 中我们还可以使用 context 来实现跨级组件之间的通信

    class Father extends Component {
    
        static childContextTypes = {
            color: React.PropTypes.string
        };
    
        getChildContext(){
            return {
                color: 'red'
            }
        }
    
        constructor (props){
            super(props)
        }
    
        render (){
            
            return <div>
                <Child />
            </div>
        }
    }
    class Child extends Component {
        static contextTypes = {
            color: React.PropTypes.string
        }
        render (){
            const {props} = this
            return <div>
                <h1 style={{background: this.context.color}}>This is Child.</h1>
            </div>
        }
    }
    

    可以看出,我们在 Father 组件中并未给 Child 组件中进行传 props ,而是在父组件中定义了,childContext,这样从这一层开始的子组件都可以拿到这个值,需要蓄意的是,使用 context 方式时候,需要写一个 getChildContext 方法来获取这个值。

    兄弟或无关组件间通信

    没有嵌套关系的,那只能通过影响全局的一些机制去实现。这样看,自定义事件机制不失为一种很好的方案。在这边使用了 EventEmitter 模块(npm包 node的基础模块)进行通信。

    import React, {Component,PropTypes} from 'react'
    import ReactDom from 'react-dom'
    import {EventEmitter2} from 'eventemitter2'
    
    var emitter = new EventEmitter2()
    
    class First extends Component {
        constructor(props){
            super(props)
            this.state = {
                data: 'init First'
            }
    
            emitter.on('changeFirstText', this.changeText.bind(this))
        }
        changeText( msg ){
            this.setState({
                data: 'First change success: origin ' + msg
            })
        }
        render (){
            return <div>
                <h1>{this.state.data}</h1>
            </div>
        }
    }
    class Second extends Component {
        handleClick(){
            emitter.emit('changeFirstText', 'Second')
        }
        render (){
            return <div onClick={ this.handleClick.bind(this) }>
                <button>点击修改 First 组件内容</button>
            </div>
        }
    }
    

    在 First 中注册了自定义事件,changeFirstText,并且绑定好回调函。emitter.on('changeFirstText', this.changeText.bind(this))
    在 Second 当用户点击发送信息请求时,在 handleClick 中,触发 changeFirstText 事件,并且把需要的信息传给过去。emitter.emit('changeFirstText', 'Second')

    相关文章

      网友评论

      • 现_状:您好问下,react中什么样的组件才可以叫做父子组件
        现_状:@骚辉_iron_whale 哦,谢谢:blush:
        高少辉_骚辉:@Sevenyears_fe8e 在一个组件中调用了另一个组件,这个组件就是那个被组件的父组件
      • 莫名小晟:这个方法有点类似于Vue里面的event bus
      • a5e8469927f8:这个方式有限制吧?两个兄弟节点必须写在一个文件中吧,不然 emitter 不一样...不知道是这样吗
        高少辉_骚辉:@小小发 :smile:
        a5e8469927f8:@骚辉_iron_whale 是的,知道保证event是同一个就好了
        高少辉_骚辉:不同文件,你只要把 event = new EventEmitter2() 也放成单独的文件,然后其他两个文件都去引用这个 event,这样模块会为你自动缓存这个 event

        ```
        const event = new EventEmitter2()
        export {
        event
        }
        ```

      本文标题:React 组件件通信2——非父子组件间通信

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