zoukankan      html  css  js  c++  java
  • 使用reflux进行react组件之间的通信

    前言

    组件之间为什么要通信?因为有依赖。
    那么,作为React组件,怎么通信?

    React官网说,

    进行 父-子 通信,可以直接pass props。
    进行 子-父 通信,往父组件传给子组件的函数注入参数。
    对于没有 父-子 关系的组件间的通信,你可以设置你自己的全局事件系统。
    详情见原文翻译文
    那么,到底如何设置全局事件系统呢,React官网没讲。

    但十美分的alloyteam的一篇文章却讲了。

    该文指出,

    1. 在组件嵌套较深时,纯props通信不适用,因为要维护很长的通信链。
    2. 在组件很多时,定义很多公共变量也不方便。
    3. 使用Pub/Sub模式有助于简化多组件通信问题。

    那么,市场上哪个Pub/Sub模式实现较好。

    在此,我推荐Reflux

    还要推荐一篇不错的Reflux的介绍和基本使用文章
    Reflux认为React组件由Store,View,Actions组成。
    View即HTML代码,它是由Store里面的原始数据经过运算得出。
    Store里面除了原始数据,还有各种原始数据处理方法。
    当View想改变Store的原始数据,可通过Actions。
    组件之间的通信,就通过这些原始数据处理方法。
    Reflux忽视组件之间的层级关系,不管父-子,子-父等等,皆可通过Store通信。
    所以,重点来了(黑板敲三下),我们要理清组件之间的依赖关系。
    那么,组件之间有哪些依赖关系呢。
    请听下回分解。
    可以剧透的是,
    依赖关系无非三种,我依赖你,你依赖我,我们互相依赖,我们互相嘿嘿嘿。
    其中,互相依赖这个场景较复杂,示例代码如下:

    // actions1.js
    module.exports = Reflux.createActions([
        'getData',
        'setData',
    ]);
    
    // PageDemo1.js
    const reactMixin = require('react-mixin');
    const Actions = require('./actions1');
    const Store = require('./store1');
    
    class Demo1 extends React.Component {
        constructor(props) {
            super(props);
            this.state = {
            };
        }
        click(){
            Actions.setData("demo1的数据已被设置");
        }
        render() {
            let t = this;
            let data = Store.data;
            if(data == null){
                return null;
            }
    
            return (
                <div className="demo1">
                    <div>{data.name}</div>
                    <button onClick={t.click.bind(t)}>设置demo1的数据</button>
                    <button onClick={t.click.bind(t)}>设置demo2的数据</button>
                </div>
            );
        }
    
        componentWillMount() {
        }
    
        componentDidMount() {
            Actions.getData();
        }
    
        componentWillReceiveProps(nextProps) {
        }
    
        shouldComponentUpdate(nextProps, nextState) {
            return true;
        }
    
        componentWillUpdate(nextProps, nextState) {
        }
    
        componentDidUpdate(prevProps, prevState) {
        }
    
        componentWillUnmount() {
        }
    }
    
    reactMixin.onClass(Demo1, Reflux.connect(Store));
    module.exports = Demo1;
    
    // store1.js
    const Actions = require('./actions');
    module.exports = Reflux.createStore({
        listenables: [Actions],
        data: null,
        onGetData:function() {
            let t = this;
            t.data = {};
            t.data.name = "demo1";
            t.updateComponent();
        },
        onSetData:function (name) {
            let t = this;
            t.data = {};
            t.data.name = name;
            t.updateComponent();
        },
        updateComponent: function() {
            this.trigger(this.data);
        },
    
        getInitialState: function() {
            return this.data;
        }
    });
    
    // actions2.js
    module.exports = Reflux.createActions([
        'getData',
        'setData',
        "setDemo1Data"
    ]);
    
    // PageDemo2.js
    const reactMixin = require('react-mixin');
    const Actions = require('./actions2');
    const Store = require('./store2');
    const Demo1 = require('../demo1');
    
    class Demo2 extends React.Component {
        constructor(props) {
            super(props);
            this.state = {
            };
        }
        click(){
            Actions.setData("demo2的数据已被设置");
        }
        setDemo1Data(){
            Actions.setDemo1Data("demo2设置demo1的数据");
        }
        render() {
            let t = this;
            let data = Store.data;
            if(data == null){
                return null;
            }
    
            return (
                <div className="demo2">
                    <div>{data.name}</div>
                    <div>
                        <button onClick={t.click.bind(t)} > 设置demo2的数据</button>
                        <button onClick={t.setDemo1Data.bind(t)} >设置demo1的数据</button>
                    </div>
                    <Demo1 />
                </div>
            );
        }
    
        componentWillMount() {
        }
    
        componentDidMount() {
            Actions.getData();
        }
    
        componentWillReceiveProps(nextProps) {
        }
    
        shouldComponentUpdate(nextProps, nextState) {
            return true;
        }
    
        componentWillUpdate(nextProps, nextState) {
        }
    
        componentDidUpdate(prevProps, prevState) {
        }
    
        componentWillUnmount() {
        }
    }
    
    reactMixin.onClass(Demo2, Reflux.connect(Store));
    ReactDOM.render(<Demo2/>, document.getElementById('App'));
    module.exports = Demo2;
    
    // store2.js
    const Actions = require('./actions2');
    const demo1Store = require('../store1');
    
    module.exports = Reflux.createStore({
        listenables: [Actions],
        data: null,
        onGetData:function() {
            let t = this;
            t.data = {};
            t.data.name = "demo2";
            t.updateComponent();
        },
        onSetData:function (name) {
            let t = this;
            t.data.name = name;
            t.updateComponent();
        },
        onSetDemo1Data:function(name) {
            demo1Store.onSetData(name);
        },
        updateComponent: function() {
            this.trigger(this.data);
        },
    
        getInitialState: function() {
            return this.data;
        }
    });
    
    
    

    如上上见,示例代码又多,又乱.
    那么,有什么构建工具能快速搭建开发环境,运行示例代码。

    在此,我推荐nowa

    只要你机子上nodejs>=4.0 版本,npm>=3.0 版本,便可以使用nowa。
    nowa 的诞生旨在解决以下痛点:

    • 每次下载或新建项目都要安装一坨开发用的依赖,而这些依赖绝大部分都是重复的,耗时又占空间(仅 babel 的一些插件就一百多兆);
    • 每个项目的构建任务配置在自己项目中维护,不方便统一维护和管理;
    • 构建配置对于很多新手用户来说还是太繁琐,迫切需要一个一站式的解决方案;
    • 项目模板的更新依赖于脚手架的发布,频繁更新用户体验不佳;
    • 希望有更流畅的开发体验;
    • 希望可以在一个地方找到所有常用的工具;
    • 希望能有一个便捷的远程调试方案;
      ……

    好了,至于使用方法大家可进入官网查看,我掩面而逃~~~

  • 相关阅读:
    盛最多水的容器
    寻找2个有序数组的中位数
    从链表中删除总和值为0的连续节点
    链表中的下一个更大节点
    链表的中间节点
    循环有序链表的插入
    设计链表
    链表组件
    扁平化多级双向链表
    将二叉搜索数转化为排序的双向链表
  • 原文地址:https://www.cnblogs.com/samwu/p/5713213.html
Copyright © 2011-2022 走看看