react-redux和redux

redux 原理:统一管理状态

redux GitHub地址:https://github.com/reduxjs/redux

redux 说明文档:`https://redux.js.org/`

  • createStore 创建容器store来保存状态的的

    • 创建容器需要传一个管理员 reducer(用户自己定义的)
    • state 属性,外界不可以直接访问
    • getState 外界可以通过store.getState 访问和获取这个状态
    • dispatch 派发一个动作,内部会调用reducer,通过这个方法修改更新状态state
    • subscribe 定阅事件(当用户派发dispatch的时候,内部会触发订阅的事件执行)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    >   > export default function createStore(reducer) {
    > > let state, listener = [],
    > > dispatch, subscribe, getState;
    > > dispatch = (action) => {
    > > reducer(state, action);
    > > listener.forEach(item => item())
    > > };
    > > dispatch({});
    > > subscribe = (fn) => {
    > > listener = [...listener, fn];
    > > return () {
    > > listener = listener.filter(item => item != fn)
    > > }
    > > };
    > > getState = () => (JSON.parse(JSON.stringify(state)));
    > > return {
    > > dispatch,
    > > subscribe,
    > > getState
    > > }
    > >
    > > }
    > >
  • combineReducers 合并状态,将多个管理员reducer合并成一个

    • 参数 {reducer1,reducer2,。。。}
    • 合并之后的状态 {reducer1:reducer1(), reducer2: reducer2(), …}
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    >   > export function combineReducers(reducers) {
    > > return (state = {}, action) => {
    > > let obj = {};
    > > for (let key in reducers) {
    > > obj[key] = reducers[key](state[key], action)
    > > }
    > > return obj;
    > > }
    > > }
    > >
    > >

react 组件中使用redux

  • 定义功能(动作)常量,一般单独放在一个js文件中,action-types.js

    1
    2
    >   const INCREMENT = "INCREMENT"
    >
  • 定义管理员reducer,创建容器store的时候传进reducer

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    >   import action-types.js
    > function reducer(state=initState, action){
    > switch(action.type){
    > case INCREMENT:
    > return state + 1
    > ...
    > default:
    > return state
    > }
    > }
    >
  • 定义一个actions,是一个对象,每一个action都需要一个函数返回

    1
    2
    3
    4
    5
    6
    >   let actions = {
    > add: (count)=>{
    > return {type: INCREMENT, count}
    > },
    > }
    >
  • 在组件中

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    >   constructor(){
    > super();
    > // 组件状态的初始化
    > this.state = {number: store.getState().number}
    > }
    >
    > componentDidMount(){
    > this.unsubscribe = store.subscribe(()=>{
    > //将redux管理的状态映射到组件自己的状态上
    > this.setState({number: store.getState().number})})
    > }
    >
    > componentWillUnmount(){
    > //取消订阅
    > this.unsubscribe()
    > }
    >
    > render(){
    > //视图放的一定是组件自己的状态或属性
    > return <div>{this.state.number}</div>
    > }
    >
  • 派发动作

    1
    2
    >   store.dispatch(actions.add(3))
    >

react-redux

react-redux GitHub地址: `https://github.com/reduxjs/react-redux`

react-redux 说明文档: https://react-redux.js.org/

  • Provider组件,一般是在最外层使用Provider包裹起来,将store 当做属性传给他,被其包裹的组件都可以使用容器store中的状态,但是组件必须使用 connect 方法处理

  • connect 方法:将组件处理成链接状态的组件

    1
    2
    3
    4
    5
    >   connect (mapStateToProps, mapDispatchToProps)(组件)
    > //返回一个新的组件
    > //mapStateToProps:将redux中的状态映射成组件的属性
    > //mapDispatchToProps:将dispatch派发的动作映射成组件的属性。(也可以直接传一个actions,redux默认会调用 bindActionCreators ,变成dispatch)
    >
  • 在组件中使用 this.props.xxx

流程图

redux流程图

高阶函数

一个函数返回一个函数let fn = ()=>()=>()

高阶组件

一个组件,返回一个新的组件

手写react-redux

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import React from "react"
import PropTypes from "prop-types"
// Provider 是一个组件,接收一个store属性,将其内容挂载到context上,这样后代才可以有办法拿到

class Provider extends React.Component{

static childContextTypes = {
//设置上下文的类型是对象
store:PropTypes.object
};

getChildContext(){
//获取并设置后代上下文的内容
return {store:this.props.store}
}

render(){
return this.props.children
}
}


let connect = (mapStateToProps, mapDispatchToProps)=>(C)=>{
return class Proxy extends React.Component{
static contextTypes = {
store:PropTypes.object
}

constructor(props, context){
super();
//将参数mapStateToProps的解构赋值给代理组件的状态
this.state = mapStateToProps(context.store.getState())
}

componentDidMount(){
this.context.store.subscribe(()=>{
this.setState(mapStateToProps(this.context.store.getState())
})
}

render(){
return </C {...this.state}
{...mapDispatchToProps(this.context.store.dispatch)}
>
}
}
};

export {Provider, connect}
如果觉得文本对您有帮助,欢迎打赏