Redux
一. 基本概念
1.Stroe
Store是保存数据的地方,可以看成是一个数据的容器,整个应用只能有一个Store。
生成store:
import { createStore } from ‘redux’
const store = createStore(fn)
其中fn是一个函数。
2.State
Store包含所有的数据,如果想得到某一类数据,就要对Store生成快照。
State 可以通过store.getState()拿到
import { createStore } from ‘redux’
const store = create
3.Action
State的变化会导致视图的变化。但是用户只能看到呈现出来的视图,看不见state,所以用户的操作若要改变state,则必须向state发出一个通知,比如提交等,Action就是这个通知,表示State应该要发生变化了。
Action是一个对象,其中type属性是必须的,表示Action的名称。
const action = { type:'ADD_TODO', payload:'Learn Redux' };
改变数据的唯一方法就是使用Action,它会将数据的改变送到Store中
4.store.dispatch()
store.dispatch()是view发出Action的唯一方法
import { createStore } from 'redux'; const store = createStore(fn) store.dispatch({ type:'ADD_TODO', payload:'Learn Redux' });
Action作为store.dispatch方法的参数
5.Reducer
Store收到了Action,必须给出一个新的State,这样用户的视图才会发生变化,这个就是State的计算过程。
const reducer = function(state,action){ // ...... return new_state; }
实际应用中,store.dispatch方法会触发Reducer的自动执行。为此,Store需要知道Reducer函数,在生成Store的时候将reducer传入,如下:
import { createStore } from 'redux';
const store = createStore(reducer);
注意:reducer是一个纯函数。
6.store.subscribe()
Store允许使用store.subscribe方法设置监听函数,一旦State发生变化,就自动执行这个函数。
import { createStore } from 'redux'; const store = createStore(reducer); store.subscribe(listener);
总结:
(1)createState创建一个store,它是所有数据的一个容器
(2)getState:得到一个state,它是某一个时间点或者某个对象的数据
(3)Action:view发出的通知,它是对store的一个改变,送去改变后的数据
(4)reducer:是对Action的一种计算,返回的是一个新的state
(5)dispath:执行reducer这种计算(要先将reducer传入store中)
(6)subscribe:对store状态的监听
7.Reducer的拆分
实际应用中state和action数量可能使十分多的,如果Reducer函数过于庞大,肯定不利于维护,
所以可以将每个reducer分开来写,最后再把它们全部合起来。
import { combineReducers } from 'redux' const chatReducer = combineReducers({ chatLog, statusMessage, userName }); export default todoApp;
这里的chatLog,statusMessage,userName就是每个子reducer。
8.工作流程
(图片来自http://www.ruanyifeng.com/blog/2016/09/redux_tutorial_part_one_basic_usages.html)
------------------------------------------------------------------------------------------------------------
回顾了Redux的一些基本概念,接下来介绍react-redux
1.安装:
npm install --save react-redux
2.Provider
react-Redux提供了<Provider/>,这能够让你的整个应用的范围内(provider包裹内)使用一个Store。
import React from "react"; import ReactDOM from "react-dom"; import { Provider } from 'react-redux'; import { reducer } from '....'; import { createStore } from 'redux'; import App from '....'; const store = createStore(reducer); ReactDOM.render( <Provider store={ store }> <App/> </Provider>, document.getElementById("root") );
3.connect
React-Redux 提供一个connect 函数来将你的组件和store连接起来
import { connect } from "react-redux"; import { increment, decrement, reset } from "./actionCreators"; // const Counter = ... const mapStateToProps = (state /*, ownProps*/) => { return { counter: state.counter }; }; const mapDispatchToProps = { increment, decrement, reset }; export default connect( mapStateToProps, mapDispatchToProps )(Counter);
mapStateToProps:表示传入state中的state数据(方法的形式)
mapDispatchToprops:表示传入state中的方法
Counter:的位置时要将上面的数据和方法用到counter组件中去。这样在counter中就可以直接用this.props. 。。。使用传入的数据和方法。
这里的connect可以使用装饰器装一波,更加直观:
import React from "react" import { connect } from "react-redux" import register from "./register/register" @connect( state=>state.main, { register } ) class App extends React.Component{ render(){ ...... } }
与上面一样这里connect中的两个参数就是mapStateToProps和mapDispatchToprops
说明:用装饰器需要安装模块babel-plugin-transform-decorators-legacy
,然后在babel中配置:
{ "plugins":[ "transform-decorators-legacy" ] }