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组件名。
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 calledownProps
, 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)
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
此场景三个关键点
- 首先mapDispatch是一个function,入参是默认的 `dispatch` 或者` (dispatch, ownProps)`
- 返回的对象的每个属性都会变成组件的一个props
- 对象的每个属性都是一个function
使用 bindActionCreators
来定义functionbindActionCreators
accepts two parameters:
- A
function
(an action creator) or anobject
(each field an action creator) dispatch
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
store
参考此链接,大致都是说怎么利用 react.context实现的redux, 以及如果自定义context, 如何设置多个store 的一些操作