//compose 组成 combine 联合
import {applyMiddleware, createStore, compose, combineReducers} from 'redux';
import { bindActionCreators } from "redux";
import {Provider} from 'react-redux'
Redux则是把数据全部放到props里面,通过各种connect,bind等打通props和store的连接。
redux获取store中的数据
引入store,使用store.getState()方法,获取state
Action 是一个对象。其中的type属性是必须的,表示 Action 的名称。其他属性可以自由设置
const action = {
type: 'ADD_TODO',
payload: 'Learn Redux'
};
上面代码中,Action 的名称是ADD_TODO,它携带的信息是字符串Learn Redux。
可以这样理解,Action 描述当前发生的事情。改变 State 的唯一办法,就是使用 Action。它会运送数据到 Store。
(1)Reducer:纯函数,只承担计算 State 的功能,不合适承担其他功能,也承担不了,因为理论上,纯函数不能进行读写操作。
(2)Action:存放数据的对象,即消息的载体,只能被别人操作,自己不能进行任何操作。
(1)、单一数据源
整个store被储存在一个Object tree(对象树)中,并且这个Object tree只存在于唯一一个store中
(2)、state是只读的
唯一改变state的方法就是触发action,action是一个用于描述已发生事件的普通对象
(3)、使用纯函数来修改(reducer)
为了描述action如何改变state tree,你需要编写reducers
redux的工作流程
如果我们有一个组件,那么想要获取数据就需要从Store中获取数据,当组件需要改变Store数据的时候。需要创建一个Action,然后通过 dispatch(action) 传递给Store,然后Store把Action转发给Reducers. Reducers会拿到previousState(以前的state数据) 和action。然后将previousState和action进行结合做新的数据(store)修改。然后生成一个新的数据传递给Store 。Store发送改变那么View也会发生改变
创建reducer.js
这个函数里面有2个参数一个是state,另一个是action。
state指的是store中的数据
action指的是View修改数据的时候传递过来的action
这个函数必须返回一个新的数据,而且还不能对老的数据进行修改(Reducer函数中不能改变state,必须返回一个全新的对象)
我们可以先把这个state设置一个默认值defaultState。在defaultState这个对象中我们可以定义一些初始的数据
十、纯函数
同样的输入必须得到同样的输出
约束:
不得修改参数
不能调用系统I/O的API
不能调用Date.now()或者Math.random()等不纯的方法,因为每次得到值是不一样的结果
十一、redux与flux的区别
Redux没有Dispatcher,且不支持多个store,Redux只有一个单一的store和一个根级的reducer函数。随着应有的不断变大,根级的reducer要拆分成多个小的reducers,分别独立的操作state的不同部分,而不是添加新的 stores。这就像一个 React 应用只有一个根级的组件,这个根组件又由很多小组件构成
https://segmentfault.com/a/1190000011474522?utm_source=tag-newest
https://www.jb51.net/article/137796.htm
https://segmentfault.com/a/1190000008491558
https://www.cnblogs.com/nanianqiming/p/9880391.html
https://www.cnblogs.com/nanianqiming/p/9873695.html
https://www.cnblogs.com/nanianqiming/p/9870194.html
https://blog.csdn.net/jyee721/article/details/94362580
一、安装
cnpm install --save redux-actions
二、为什么使用 redux-actions
reducer使用switch case语句进行action类型判断,当action很多时候,reducer内容就不那么直观了。redux-actions简化了reducer和action的联系
三、基本使用
1、创建action/actionCreator.js
import { createAction } from 'redux-actions';
export const addnum = createAction('ADDNUM')
2、组件中引入使用
import React,{Component} from "react";
import store from "./store"
import {addnum} from "./action/actionCreator"
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(){
store.dispatch(addnum());
}
handleUpdate(){
this.setState(store.getState())
}
}
3、reducer中使用
import {handleActions} from 'redux-actions';
const defaultState = {
n:10
}
export default handleActions({
ADDNUM: (state, action) => {
let newState = {...state};
newState.n++;
return newState;
},
}, defaultState)
手动封装一个简易版的redux
export let createStore = (reducer)=>{
//定义默认的state
let state = {};
//定义默认的action
let actionTypes = "@@redux/INIT"+Math.random();
let initAction = {type:actionTypes}
//将所以需要监听的函数放在这个里面
let listeners = []
//定义getState函数
let getState = ()=>state;
//定义事件订阅函数
let subscribe = (cb)=>{
listeners.push(cb);
}
//定义事件派发函数 用来调用action
let dispatch = (action=initAction)=>{
//调用reducer获取新的state
state = reducer(state,action);
//遍历所以需要监听的函数
listeners.map((cb)=>{
cb();
})
}
dispatch();
return {
getState,
dispatch,
subscribe
}
}
const combineReducers = (reducers)=>{
let newState = {};
return function(state,action){
for(var key in reducers){
newState[key] = reducers[key](state[key],action)
}
return newState;
}
}