redux 和 react没任何关联!

基本概念

action

行为 它是一个对象 里面必有type来指定其类型 这个类型可以理解为你要做什么,reducer要根据action的type来返回不同的state 每个项目有且可以有多个action

reducer

专门处理state的工厂 给他一个旧数据它会根据不同action.type返回新的数据 也就是:旧state + action = 新state 每个项目有且可以有多个reducer

store

store本质上是一个状态树,保存了所有对象的状态。任何UI组件都能直接的从store访问特定对象的状态。每个项目有且只能有一个store

store.getState() 可以获取当前的状态树

分发&订阅

store.dispatch(actionObj)
dispatch的作用就是告诉reducer 我给你action, 你要根据我的action.type返回新的state。 然后reducer就会根据action的type,返回新的state。
store.subscribe(() =>{})作用就是每当reducer返回新的数据 它就会自动更新页面 把UI组件的state更新下

react-redux

为了把复杂的东西简单化,react官方提供的redux解决方案,帮助更好的使用redux

基础概念

Provider

它是react-redux 提供的一个 React 组件,作用是把state传给它的所有子组件,也就是说 当你用Provider传入数据后 ,下面的所有子组件都可以共享数据(把Provider组件包裹在最外层的组件)

connect

高阶组件,传递一个组件返回一个新组件

connect 返回一个新的函数,可以接收一个待包装的组件

有四个参数([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])
作用: 把指定的state和指定的action与React组件连接起来,后面括号里面写UI组件名。

  1. App = connect(mapStateToProps, mapDispatchToProps)(App)
  • mapStateToProps:每当store state发生变化时,就被调用。接收整个store state,并且返回一个该组件所需要的数据对象 应该定义为一个函数

    function mapStateToProps(state, ownProps?)
    

    It should take a first argument called state, optionally a second argument called ownProps, and return a plain object containing the data that the connected component needs.

  • mapDispatchToProps:这个参数可以是一个函数对象

    • 如果是一个函数,一旦该组件被创建,就会被调用。接收dispatch作为一个参数,并且返回一个能够使用dispatch来分发actions的若干函数组成的对象
    • 如果是一个action creators构成的对象,每一个action creator将会转化为一个prop function并会在调用时自动分发actions。注意: 我们建议使用这种形式

      核心步骤

      这个demo诠释的很完整,迷惑时可以继续参考
  • 创建各种reducer, 多个通过 combineReducers 来合并

    reducer其实就是一个函数,通过action type将旧的 state 转换成 新的 state 最好的做法是一个reducer单独一个文件处理,参考这里 redux/reducers/todos.js

export default function(state = initialState, action) {
  switch (action.type) {
    return newState   
  }
  • 通过reducer创建 store ```typescript import { createStore } from “redux”; import rootReducer from “./reducers”;

// 根据reducer创建一个store,可以是多个reducer,通过combineReducers来合并多个 const store = createStore(rootReducer);

作为props给 Provider

组件~~~~ ,


- 链接action mapDispatchToProps 
> 上面的步骤已经将reducer & store 绑定起来,
> 现在只需要将对应的组件和redux关联起来
> 如下方 addTodo 这个action 绑定到了 mapDispatchToProps ,AddTodo组件中就存在一个了this.pros.addTodo 属性,当主动触发dispatch时 就能通过redux全局通知 对应的action,生成新的state,随即通知对应的subscription组件re-render

process: define an action creator, wrap it in another function that looks like `(…args) => dispatch(actionCreator(…args))`, and pass that wrapper function as a prop to your component.
```typescript
export default connect(null, 
  {addTodo} 
  )(AddTodo);
  • 链接 state mapStateToProps

    注册组件的state变化的监听,当state发生变化时,从全局state中拿数据设置到该组件中的props

export default connect(mapStateToProps)(TodoList);

connect调用方式

当然细节还是参考官网 默认的dispatch props场景

Do Not Subscribe to the Store Subscribe to the Store
Do Not Inject Action Creators connect()(Component) connect(mapStateToProps)(Component)
Inject Action Creators connect(null, mapDispatchToProps)(Component) connect(mapStateToProps, mapDispatchToProps)(Component)

核心说明备注

mapStateToProps

mapStateToProps is used for selecting the part of the data from the store that the connected component needs

  • store state变化时都会被调用
  • 返回一个完整的store state,但是需要按组件需要返回state

    state

    必须定义为函数,如果不想每次都被回调,可以定义为 null 或者 undefined ,方法的两种定义方式 ```typescript function mapStateToProps(state, ownProps?) 或者 箭头function const mapState = (state) => {}

改函数至少必须保证 state 参数的传递,当然这个名字随便取啦,其实state更准确的描述应该是 state instance(因为代表了整个store state)


<a name="xeexq"></a>
#### `ownProps` (optional)
> 如果组件需要其 own props to retrieve data from the store

![image.png](https://cdn.nlark.com/yuque/0/2020/png/92723/1583371149169-66fff435-6dd7-4747-9f14-78b3c422e962.png#align=left&display=inline&height=206&name=image.png&originHeight=578&originWidth=1464&size=377161&status=done&style=none&width=523)
<a name="m825t"></a>
#### 
<a name="QC76C"></a>
#### Return 返回值
> 关键是:return a plain object that contains the data the component need

- Each field in the object will become a prop for your actual component(对象的每个field都会变成组件的props)
- The values in the fields will be used to determine if your component needs to re-render

![image.png](https://cdn.nlark.com/yuque/0/2020/png/92723/1583371394951-20d35c52-fca8-48a0-ac1f-0315977bb5b2.png#align=left&display=inline&height=170&name=image.png&originHeight=406&originWidth=1264&size=197200&status=done&style=none&width=528)

<a name="LF9mP"></a>
### mapDispatchToProps
> `mapDispatchToProps` is used for dispatching actions to the store.

`store.dispatch`  to dispatch an action. This is the only way to trigger a state change.<br />两种方式来dispatch actions

- By default, a connected component receives `props.dispatch`  and can dispatch actions itself.
- connect can accept an argument called `mapDispatchToProps`, which lets you create functions that dispatch when called, and **pass those functions as props to your component**.
<a name="IGUhb"></a>
#### Default: `dispatch` as a Prop
如果不指定`connect`第二个参数,下述三个写法都是一致的<br />组件就会默认接收 `props.dispatch`
```typescript
connect()(MyComponent)
// which is equivalent with
connect(
  null,
  null
)(MyComponent)

// or
connect(mapStateToProps /** no second argument */)(MyComponent)

image.png

Two Forms of mapDispatchToProps

1、Function form: Allows more customization, gains access to dispatch and optionally ownProps

mapDispatchToProps function should return a plain object:

  • Each field in the object will become a separate prop for your own component, and the value should normally be a function that dispatches an action when called.
  • If you use action creators ( as oppose to plain object actions ) inside dispatch, it is a convention to simply name the field key the same name as the action creator

image.png
此场景三个关键点

  - 首先mapDispatch是一个function,入参是默认的 `dispatch` 或者` (dispatch, ownProps)`
  - 返回的对象的每个属性都会变成组件的一个props
  - 对象的每个属性都是一个function

使用 bindActionCreators 来定义function
bindActionCreators accepts two parameters:

  1. A function (an action creator) or an object (each field an action creator)
  2. dispatch

image.png

Manually Injecting dispatch
// If the mapDispatchToProps argument is supplied, 
// the component will no longer receive the default dispatch
function mapDispatchToProps(dispatch) {
  return {
    dispatch,
    ...bindActionCreators({ increment, decrement, reset }, dispatch)
  }
}

2、Object shorthand form: More declarative and easier to use(RECOMMEND

if you pass an object full of action creators instead of a function, connect will automatically call bindActionCreators for you internally.(其实传对象内部也是用来bindActionCreators进行组装)
NOTE:

  • Each field of the mapDispatchToProps object is assumed to be an action creator
  • Your component will no longer receive dispatch as a prop

image.png

store

参考此链接,大致都是说怎么利用 react.context实现的redux, 以及如果自定义context, 如何设置多个store 的一些操作