Redux 使用流程与个人心得(一)

Redux 是React生态中重要的组成部分。很多人都说,简单的应用可以不用此工具。但是我个人认为,中小型应用使用的话,可以使文件结构更加规范,代码可读性更强。因为React提出将展示组件与容器组件分离的思想,所以降低了React 与Redux之间的耦合度。

网上广为流传的Redux流向图,可以帮助我们更好地理解并使用。
Redux Flux.png

我个人粗浅的理解是:
Store的角色是整个应用的数据存储中心,集中大部分页面需要的状态数据;
ActionCreators ,view 层与data层的介质;
Reduce ,接收action并更新Store。
所以流程是 用户通过界面组件 触发ActionCreator,携带Store中的旧State与Action 流向Reducer,Reducer返回新的state,并更新界面。

所以也可以按照这个流程思想,来构建代码的结构了。


实现一个很简单的结构.png

上图实现的就是输入输出的东西。输入框内输入一些内容,confirm后,label显示相应内容。

最开始
先安装几个库

npm install --save prop-types
npm install --save react-redux
npm install --save redux

1、首先构造界面

component/AddName.js

-这是一个纯React代码 ,结构清晰。

//component/AddName.js
import React, { Component } from 'react';
import PropTypes from 'prop-types'

class AddName extends Component {
  //声明属性
  static propTypes = {
    lastname:PropTypes.string.isRequired,
    addNameCreater:PropTypes.func.isRequired,
    lastage:PropTypes.number.isRequired,
    addAgeCreater:PropTypes.func.isRequired,
    addNameAsync:PropTypes.func.isRequired
  }
//点击事件
  handlerFunc = () =>{
    const inputName = this.refs.inputValueTest.value;
    this.props.addNameCreater(inputName);
  }
  handlerAgeFunc = () =>{
    const inputage = this.refs.inputValueAge.value;
    this.props.addAgeCreater(inputage);
  }
  handlerAsyncFunc = () =>{
    const inputName = this.refs.inputValueTest.value;
    this.props.addNameAsync(inputName);
  }
//渲染界面
  render() {
    const {lastname,lastage} = this.props;   
    return (
      <div>
        <header className="App-header">
          <h1 className="App-title">Welcome to React</h1>
        </header>
        <label> {lastname} </label><br/>
        <input ref="inputValueTest" /><br/>
        <button onClick={this.handlerFunc}>confirm</button><br/>

        <label> {lastage} </label><br/>
        <input ref="inputValueAge" />
        <button onClick={this.handlerAgeFunc}>confirm</button><br/>

        <button onClick={this.handlerAsyncFunc}>Async Confirm</button><br/>
      </div>
    );
  }
}

export default AddName;


2、然后,根据流程图,我们需要定义一些操作了,也就是ActionCreator.它会传达用户的操作信息以及一些数据

先定义一些常量供我们使用,这里就两种操作,一是添加名字,二是添加年龄,实际都一样。为了后面实现reducer的合并强行写了俩。这写常量一般都定义在actionTpye文件中

Redux/actionType.js

export const ADDNAME = 'ADDNAME'
export const ADDAGE = 'ADDAGE'

接着就是写ActionCreator ,定义了一些操作类型,告诉store自己是干什么的,需要什么样的数据。

Redux/actions.js

import { ADDNAME,ADDAGE } from "./action-type";

//包含所有的action creator
export const addNameCreater = (name) =>({type:ADDNAME,data:name})
export const addAgeCreater = (age) => ({type:ADDAGE,data:age})
export const addNameAsync = (name) =>{
    return dispatch =>{
        setTimeout(()=>{
            dispatch(addNameCreater(name))
        },2000);
    }
}

3、Reducer 会接收到action的信息。将会进行状态(数据)的处理,相当于react中的setState()的功能。如果有多个reducer ,可以使用combineReducers方法将其合并,并暴露出去。

Redux/reducer.js

//包含n个reducer函数的模块
import {ADDNAME, ADDAGE} from './action-type'
import {combineReducers} from 'redux'
function addName(state='initRedux',action){ //形参默认值
    switch(action.type){
        case ADDNAME:
            return action.data
        default:
            return state
    }
}
function addAge(state=0,action){
    switch(action.type){
        case ADDAGE:
            return action.data
        default:
            return state
    }
}

export const finalReducer = combineReducers({
    addName,addAge
})

其中state='initRedux' 、state=0 相当于我们在React组件内部初始化state.

4、一切操作还是基于Store 的。类似于中央集权。所以还要把Store建立出来

Redux/store.js

import {createStore,applyMiddleware} from 'redux'
import {finalReducer } from './reducers'
import thunk from 'redux-thunk'
//生成store对象
const store = createStore(finalReducer,applyMiddleware(thunk));//内部会第一次调用reducer函数,得到初始state 

export default store

因为reducer会更新Store中的状态(数据),所以需要引入reducer ,并创建store.

到此,流程图到这里就走完了。不过2、3、4都是redux中负责接管React 状态的功能。1是React负责展示的组件。两者并没啥关系。既然有了展示组件,接下来就要有容器组件了。也就是能够将React与redux相关联的一个组件。

5、构建容器组件

containers/App.js

import React from 'react'
import {connect} from 'react-redux'
import {addNameCreater,addAgeCreater,addNameAsync} from '../redux/actions'
import AddName from '../component/AddName'
export default connect(
    state => ({
        lastname:state.addName,
        lastage:state.addAge
    }),
    {addNameCreater,addAgeCreater,addNameAsync}
)(AddName)

这里用到了react- redux中的connect 。可以将React与redux关联起来。AddName就是第一步写的组件名。state中关联了React中的属性。这里面涉及到两个API,到第二章详细描述。

6、添加store

src/index.js

import React from 'react';
import ReactDOM from 'react-dom';
import {Provider} from 'react-redux'

import App from './containers/App'
import store from './redux/store'

ReactDOM.render((
//使用Provider 组件将APP主组件包裹住,这样内部组件都有Store种提供的属性。
    <Provider store={store}>
        <App/>
    </Provider>
), document.getElementById('root'));

这样就OK了。

文件结构.png

上图是主要的文件结构,
-redux 集中管理状态(数据)
-component 专注于React 展示组件部分
-containers 集中处理React与redux交互的部分

此外,redux还可以处理一些异步请求。这样的话。可以做到data 和view 的管理分离,增强了工程结构的可读性与可维护性。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容