Flux plus => Redux
上一篇文章中,提到了React中的Flux架构,尽管理解起来相对容易,但是随着项目体系的增加,需要实时地将容器组件(处理页面逻辑)与UI组件(负责页面渲染)分离,手动地来降低各个模块之间的耦合度。
而Redux的出现,解决了过于复杂地拆分,可以更高效地管理多个store,并且不需要对每个视图更新函数做绑定。
![](https://img.haomeiwen.com/i19000302/55ee7315901b769b.png)
当组件要修改数据的时候,通过dispatch发送action给store,但是store的内部将action传递给了reducers,reducers进行了数据的更改,将新的state返回给store,最后通过store再次更新视图。
一、快速上手
- 安装
cnpm i redux -S
- createStore函数,专门用来创建公共的内存空间store,将这里的数据渲染到页面上。
store是一个对象,里面有几个常用的函数:getState / dispatch / subscribe
参数:回调函数reducers
import {createStore} from "redux";
import reducers from "./reducers"
const store = createStore(reducers);
export default store;
- reducer.js
必须是一个纯函数(输入一定,输出也一定),函数中有两个参数:1. state 2. action;Redux为了防止报错,默认给了参数初始值 。
当前函数必须有一个默认的state
纯函数内部的state只允许读,不允许修改
当前函数必须要返回一个state,返回的state会替换原来的state
state = reduce(state , action)
//存储初始的数据
const defaultState = {
n:10
}
export default (state=defaultState,action)=>{
switch(action.type){
case "NUM_ADD":
var numState = JSON.parse(JSON.stringify(state));
numState.n++;
return numState;
}
return state
}
- App.js
import React, { Component } from 'react'
import store from "./store"
export default class App extends Component {
constructor() {
super();
this.state = store.getState();
store.subscribe(this.handleUpdate.bind(this))
}
render() {
let { n } = this.state;
return (
<div>
<h2>{n}</h2>
<button onClick={this.handleClick.bind(this)}>点击</button>
</div>
)
}
handleClick() {
var action = {
type: "NUM_ADD"
}
store.dispatch(action);
}
handleUpdate() {
this.setState(store.getState())
}
}
二、combineRedux
简单概括,该方法用来合并多个reducers
- 安装
cnpm i redux-devtools-extension -D
- 引入
import { createStore, combineReducers } from "redux"
import { composeWithDevTools } from "redux-devtools-extension";
- combineReducers合并多个reducers
import { createStore, combineReducers } from "redux";
import { composeWithDevTools } from 'redux-devtools-extension';
//combineReducers 合并多个reducers
import num from "./reducers/num"
import todo from "./reducers/todo"
const reducers = combineReducers({
num,
todo
})
const store = createStore(reducers, composeWithDevTools());
export default store;
三、Redux封装
- store/index.js
store中要返回一个对象,包含三个常用的方法getState/dispatch/subscribe
import { createStore, combineReducers } from "../redux/index"
import num from "./reducers/num"
import todo from "./reducers/todo"
const reducers = combineReducers({
num,
todo
})
const store = createStore(reducers);
//store应该是一个对象 getState dispatch subscribe
export default store;
- store/reducer/num.js
这里的state要有默认值defaultState,没有时为undefined(注意:不能赋值为null)
const defaultState = {
n: 10
}
export default (state = defaultState, action) => {
switch (action.type) {
case "NUM_ADD":
var numState = Object.assign({}, state);
numState.n++;
return numState;
}
return state;
}
- redux/index.js
上面的action中默认有一个初始值。
getState返回state值;
subscribe监听eventList中的函数;
dispatch接收action,传入state和action触发reducer处理逻辑
var initAction = { type: "@@/redux" }
export const createStore = (reducer) => {
let eventList = [];
let state = {};//默认为undefined
// 返回state
let getState = () => state;
// 监听eventList中的函数
let subscribe = (callback) => {
eventList.push(callback);
}
let dispatch = (action) => {
state = reducer(state, action);
eventList.forEach(cb => {
cb();
})
}
// dispatch第一次默认会调用
dispatch(initAction);
return {
getState,
subscribe,
dispatch,
}
//combineReducers的返回值是一个函数
export const combineReducers = (reducers)=>{
var newState = {};
return (state,action)=>{
for(var key in reducers){
newState[key] = reducers[key](state[key],action);
}
return newState;
}
}
}
网友评论