浅说Flux开发

浅说Flux开发

前段时间,写了篇关于React的文件:React:组件的生命周期,比较详细的说了下React组件的生命周期。

说道 React,很容易可以联想到 Flux。今天以 React 介绍及实践教程 一文中的demo为示例,简单说说 Flux 的开发方式。

Flux是什么

Flux 是 Facebook 用户建立客户端 Web 应用的前端架构, 它通过利用一个单向的数据流补充了 React 的组合视图组件。

Flux 的设计架构如图:

Flux 架构有三个主要部分:Dispatcher 、Store 和View(React 组件)。Store 包含了应用的所有数据,Dispatcher 负责调度,替换了 MVC中 的Controller,当 Action 触发时,决定了 Store 如何更新。当 Store变化后,View 同时被更新,还可以生成一个由Dispatcher 处理的Action。这确保了数据在系统组件间单向流动。当系统有多个 Store 和 View 时,仍可视为只有一个 Store 和一个 View,因为数据只朝一个方向流动,并且不同的 Store 和 View 之间不会直接影响彼此。

Flux的简单开发

在颜色盘的demo中,对界面的组件划分是这样的:

用户在 ColorPanel(View) 上产生一个 Action,Action 将数据流转到 Dispatcher,Dispatcher 根据 Action 传递的数据更新 Store,当 Store变化后,View 同时被更新。

(若你要获取本文的源代码,可以戳此:Flux-Demo

Store

Store 包含了应用的所有数据,并负责更新 View(ColorPanel),为简单,简化 Store 的定义:

let EventEmitter = require(‘events‘).EventEmitter;
let emitter = new EventEmitter();

export let colorStore = {
    colorId: 1,

    listenChange(callback){
        emitter.on(‘colorChange‘, callback);
    },

    getColorId(){
        return this.colorId
    },

    setColorId(colorId){
        this.colorId = colorId;
        emitter.emit(‘colorChange‘);
    }
};

Dispatcher

Action 要靠 Dispatcher 去调度,才能更新 Store,并有 Store 去更新对应的 View 组件。定义一个 colorDispatcher 用于调度:

import {Dispatcher} from ‘flux‘;
import {colorStore} from ‘./colorStore‘;

export let colorDispatcher = new Dispatcher();

colorDispatcher.register((payload) => {
    switch (payload.action){
        case ‘CHANGE_COLOR_ID‘:
            colorStore.setColorId(payload.colorId);
            break;
    }
});

Action

当鼠标悬浮在 ColorBar 中的一个颜色框时,根据颜色框 ID 的变化,ColorDisplay 显示对应的颜色。我们定义一个 Action 为 CHANGE_COLOR_ID:

import {colorDispatcher} from ‘./colorDispatcher‘;

export let colorAction = {
    changeColorId(colorId){
        colorDispatcher.dispatch({
            action: ‘CHANGE_COLOR_ID‘,
            colorId: colorId
        })
    }
};

建议定义的 Action 符合 FSA 规范。

View

按照上图的组件划分,我们渲染出界面:

ColorDisplay:

import React, {Component} from ‘react‘;

class ColorDisplay extends Component {
    shouldComponentUpdate(nextProps, nextState){
        return this.props.selectedColor.id !== nextProps.selectedColor.id;
    }

    render(){
        return (
            <div className = ‘color-display‘>
                <div className = {this.props.selectedColor.value}>
                    {this.props.selectedColor.title}
                </div>
            </div>
        )
    }
}

export default ColorDisplay;

ColorBar:

import React, {Component} from ‘react‘;
import {colorAction} from ‘../flux/colorAction‘;
import {colorStore} from ‘../flux/colorStore‘;

class ColorBar extends Component {
    handleHover(colorId){
        let preColorId = colorStore.getColorId();
        if(preColorId != colorId){
            colorAction.changeColorId(colorId);
        }
    }

    render(){
        return (

            <ul>
                {/* Reaact中循环渲染元素时, 需要用key属性确保正确渲染, key值唯一*/}
                {this.props.colors.map(function(color){
                    return (
                        <li key = {color.id}
                            onMouseOver = {this.handleHover.bind(this, color.id)}
                            className = {color.value}>
                        </li>
                    )
                }, this)}
            </ul>
        )
    }
}

export default ColorBar;

ColorPanel:

import React, {Component} from ‘react‘;
import ColorDisplay from ‘./colorDisplay‘;
import ColorBar from ‘./colorBar‘;
import {colorStore} from ‘../flux/colorStore‘

class ColorPanel extends Component {

    constructor(props){
        super(props);
        this.state = {
            selectedColor: this.getSelectedColor(colorStore.getColorId())
        };
        colorStore.listenChange(this.onColorHover.bind(this));
    }

    getSelectedColor(colorId){
        if(! colorId){
            return null
        }

        let length = this.props.colors.length;
        let i;
        for(i = 0; i < length; i++) {
            if(this.props.colors[i].id === colorId){
                break;
            }
        }
        return this.props.colors[i];
    }

    shouldComponentUpdate(nextProps, nextState){
        return this.state.selectedColor.id !== nextState.selectedColor.id;
    }

    render(){
        return (
            <div>
                <ColorDisplay selectedColor = {this.state.selectedColor} />
                <ColorBar colors = {this.props.colors}  />
            </div>
        )
    }

    onColorHover(){
        let colorId = colorStore.getColorId();
        this.setState({
            selectedColor: this.getSelectedColor(colorId)
        })
    }
}

ColorPanel.defaultProps = {
    colors: [
        {id: 1, value: ‘red‘, title: ‘red‘},
        {id: 2, value: ‘blue‘, title: ‘blue‘},
        {id: 3, value: ‘green‘, title: ‘green‘},
        {id: 4, value: ‘yellow‘, title: ‘yellow‘},
        {id: 5, value: ‘pink‘, title: ‘pink‘},
        {id: 6, value: ‘black‘, title: ‘black‘}
    ]
};

export default ColorPanel;

App:

var ReactDom = require(‘react-dom‘);
import React from ‘react‘;
import ColorPanel from ‘./panel/colorPanel‘;

require(‘./app.css‘);

window.onload = function () {
    ReactDom.render(<ColorPanel />, document.getElementById(‘demos‘));
}

最终的的界面如下:

总结

本文简单的说了下如何利用 Flux 去开发实际应用,对于负载要求不高的应用,Flux 是完全可以使用的,复杂的富应用则可以借助 Redux + React 构建,Redux 负责数据分发和管理,其数据流的可控性比 Flux 更强,React 则依旧负责 View,但二者并不能直接连接,需要依赖 react-redux

若你要获取本文的源代码,可以戳此:Flux-Demo

原文出处:http://www.ido321.com/1658.html

时间: 2024-11-05 06:26:19

浅说Flux开发的相关文章

还在纠结 Flux 或 Relay,或许 Redux 更适合你

重磅消息,Redux 1.0 发布,终于可以放心用于生产环境了! 在这个端应用技术膨胀的时代,每天都有一大堆框架冒出,号称解决了 XYZ 等一系列牛 X 的问题,然后过一段时间就不被提起了.但开发的应用还是需要维护的!所以选择框架时不要只顾着自己用着爽,还要想着以后别人接手时的难易度. 因为 Flux 本身约定不够细致,如何做异步.如何做同构这些非常普遍的问题,官方都没有给出详细的说明.还有 store,view 里一大堆重复代码,极速膨胀的 action 等问题.这也难免会冒出一堆“改良”性的

react 开发

总结下过去一年的 react 开发经历 用的是 flux 开发流程,中间穿插一些 emitter,大体上是服从下图规范 flux 开发是以广播形式进行 trigger 的,通过 AppConstants 注册监听语句,UIActions 注册触发函数,AppDispatcher.register接收事件,根据UIActions 的  actionType 是否等于 AppConstants 的语句块来判断是否触发对应逻辑. 比较好用的 react 插件有 react-modal, rc-slid

React: 研究Redux的使用

一.简介 在上一篇文章中,大概讲了下Flux设计模式的使用,在末尾顺便提了一些基于Flux的脚本库,其中Redux已经毋庸置疑地成为了众多脚本库的翘楚之一.是的,Redux是基于Flux开发的,Redux库的尺寸非常小,代码量少,核心目的仍是处理数据流变化的问题.Redux并不完全是Flux,它只是类Flux的脚本库,它移除了Dispatcher这个概念,现在的结构是包含Store.Action.Action生成器.以及用于修改State的Action对象.在Redux中,对于State的管理采

Flux是一个Facebook团队的前端开发架构

Flux introduction 本文组成: React 官方文档翻译 相关实践心得. 内容上是Flux的介绍,例子将会在以后写出.一旦稍微多了解一点React,很难避免听到Flux这个名词.Flux是一个Facebook团队的前端开发架构.借助单向数据流等其它机制,使得React可以发挥了更加强大的功能.比起其它的框架,Flux更像是一种模式,我们可以投入较少的学习成本,快速上手Flux. Flux应用有三个主要的组成部分:调度者(dispatcher), 仓库(stores),视图(vie

[.NET开发] 浅说C#异步和同步

提到异步,那么与之对应的是什么呢?同步.那么C#的异步和同步是如何工作的呢? 首先,我们先来看看栗子: 新建一个控制台应用程序,在Program文件中添加如下代码: 1 static void Main(string[] args) 2 { 3 //计时器 4 Stopwatch watch = new Stopwatch(); 5 //开始计时 6 watch.Start(); 7 Console.WriteLine($"{DateTime.Now.ToString()} 进入Main方法,执

浅说信息安全

浅说信息安全 一.      前言 目前,信息安全事件频频发生,支付宝.携程先后中招,更有恐怖的,波兰航空的地面操作系统都被黑了.信息安全问题已经越来越严重,毫不夸张滴说,信息安全的威力绝不下于核武器,可以轻而易举地摧毁一个国家.试想一下,哪一天我们到银行发现里面的钱没了.飞机起飞不了.火车发不了班了.电网无法供电了.通信中断了等等,我们的生活会变成怎样?因此,信息安全已经是一个事关国家生死存亡的必争之地. 二.      什么是信息安全 然而,什么是信息安全?信息安全包含了哪些内容?如何做到信

Flux 架构入门教程

过去一年中,前端技术大发展,最耀眼的明星就是React. React 本身只涉及UI层,如果搭建大型应用,必须搭配一个前端框架.也就是说,你至少要学两样东西,才能基本满足需要:React + 前端框架. Facebook官方使用的是 Flux 框架.本文就介绍如何在 React 的基础上,使用 Flux 组织代码和安排内部逻辑,使得你的应用更易于开发和维护. 阅读本文之前,我假设你已经掌握了 React .如果还没有,可以先看我写的<React入门教程>.与以前一样,本文的目标是使用最简单的语

Flux --&gt; Redux --&gt; Redux React 入门 基础实例使用

本文的目的很简单,介绍Redux相关概念用法 及其在React项目中的基本使用 假设你会一些ES6.会一些React.有看过Redux相关的文章,这篇入门小文应该能帮助你理一下相关的知识 一般来说,推荐使用 ES6+React+Webpack 的开发模式,但Webpack需要配置一些东西,你可以先略过,本文不需要Webpack基础 入门,只是一些基础概念和用法的整理,更完整的内容推荐去看看文档,英文,中文 (不过我个人认为,官方文档的例子相对来说太复杂了,很难让新手马上抓住重点) (官方的例子正

2016 年做前端开发是什么体验?混乱+开倒车,这是我的体验

有人说,你有什么资格发表这种高谈阔论,实际上是这样的,我在看 lol 比赛直播的时候,有个很有名的主播说过,打到 2400 以上的都去做职业玩家了, 1800-的还在挣扎,只有 2000 徘徊的才出来做主播,的却是这样,如果你是一个能力很强的程序员,你可以驾驭任何新技术.框架,那么你的牛逼可能掩盖一些真正的问题,但是有些人偏偏把问题说成 feature . 很多前端开发以鄙视 jQuery 为荣,以 jq-free 作为吹资,这是没问题的,因为如果你的目标是 IE9+,或者移动端, MVVM 框