# Redux

Redux 是一个 Web应用 的状态管理方案

# 基本组成

  • store:一个状态容器(全局唯一),存储所有状态(state)。
  • state:状态
  • action:View 发出的一种 能让 state 发生变化 的通知
  • dispatch:View 发出 Action 的媒介
  • reducer:接收 action、state,返回一个新的 state(通过替换旧的)

alt

使用前 vs 使用后

vs

# 三个原则

  • 单一数据源: 整个应用只有唯一的 Store

  • State只读: 唯一改变 state 的方法就是 dispatch 一个 action

  • 纯行为函数: 只能通过一个 纯函数reducer 来描述修改。

# 特点

  • 遵循单向数据流
  • 每一个 state 的变化可预测
  • 状态可统一处理“修改前的校验”

# react-redux

在 React 里使用 Redux。

部分概念和上面提到的差不多,除此之外,还有一些新的概念:

# Provider

<Provider>是一个容器。

原理:通过React Context实现。

export const ReactReduxContext = React.createContext(null);

function Provider({ store, context, children }) {
  // ...
  return <Context.Provider value={contextValue}>{children}</Context.Provider>
}
1
2
3
4
5
6

在业务组件内与 connect 配合,可以实现 跨层级数据传递

# connect

是一个高阶组件,接收 2 个函数:

  • mapStateToProps:将需要的 state 注入到组件的props中

  • mapDispatchToProps:将 dispatch 注入到组件的props中

const mapStateToProps = state => {
    
}
1
2
3

除了上面的作用,还有当 state 发生变化时,通知关联的组件更新。

import {Component} from "react";
import React from "react";
import {PropTypes} from 'prop-types'

// connect是个纯函数,它返回一个组件的类定义
const connect = (mapStateToProps, mapDispatchToProps) => (WrappedComponent) => {
    class Connect extends Component {
        constructor() {
            super()
            this.state = {}
        }

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

        componentWillUnmount() {
            this.unSubscribe()
        }

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

    Connect.contextTypes = {
        store: PropTypes.object
    }

    return Connect
}

export default connect
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
# 使用示例
import React from "react";
import { connect } from "react-redux";
import { changeColorAction } from "./../../redux/action";

class Header extends React.Component {
  setColor = () => {
    const { changeColor } = this.props;
    changeColor("blue");
  };

  render() {
    const { themeColor } = this.props;

    return (
      <div>
        目前的颜色为:{themeColor}
        <button onClick={this.setColor}>改为蓝色</button>
      </div>
    );
  }
}

const mapStateToProps = (state) => ({
  themeColor: state.themeColor
});
const mapDispatchToProps = (dispatch) => ({
  changeColor: (color) => {
    dispatch(changeColorAction(color));
  }
});

export default connect(mapStateToProps, mapDispatchToProps)(Header);
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

# [实践] react-redux

1、新建reducer.js:接收 action、state,返回新的 state

2、实例化store:向 createStore 传入 reducer

3、引入Provider组件:传入store

4、注入到业务组件:利用 connect 包裹业务组件,将 statedispatch 注入到组件

react-redux-demo (opens new window)

# 参考链接

更新时间: 11/21/2021, 2:45:24 AM