Redux的基本使用&&API介绍
- Reducer
- Redux中负责响应action并修改数据的角色就是reducer
- reducer的本质实际上是一个函数,其函数签名为:reducer(previousState,action) => newStatereducer(previousState,action) => newState
- reducer 只是一个模式匹配的东西,真正处理数据的函数,一般是额外在别的地方写的(当然直接写在reducer中也没问题,只是不利于后期维护)
- 不要直接修改传入的参数previousState,最好返回一个新的对象state
- action
- 代表用户操作
- 规定一定有一个属性type,type属性一定是唯一的
- 如果所有的action都手写可能很麻烦,我们定义一个action Creaters
function addTo(num) { return { type: 'Increment', num } } export default addTo;
- store
- Store 就是保存数据的地方,你可以把它看成一个容器。整个应用只能有一个 Store。
- Redux 提供
createStore
这个函数,用来生成 Store。import { createStore } from 'redux' import reducer from './reducer' let store = createStore( reducer )
- createStore的3个参数:
- 参数1:reducer,
- 参数2:preloadedState,state的初始值,一般由服务器给出,如果给了这个值,默认会覆盖reducer里的初始值
- 参数3:enhancer,会对createStore进行增强后,再传入reducer和preloadedState,相当于一个高阶函数,返回结果:enhancer(createStore)(reducer, preloadedState)
- state
- store对象包含所有的数据,如果我们想获得当前这个时间点的数据,可以使用store.getState();
- dispatch
- 用户发出action修改state的唯一方法就是dispatch
- Store.dispatch(action);调用之后,会去执行reducer规则
- subscribe
- 对state进行监听,一旦发生变化就会执行这个函数listener
import { createStore } from 'redux'; const store = createStore(reducer); store.subscribe(listener);
- 解除监听,通过subscribe返回的函数,执行之后可以接触监听
let unsubscribe = store.subscribe(() => console.log(store.getState()) ); unsubscribe();
- 对state进行监听,一旦发生变化就会执行这个函数listener
connect&&Provier的使用
- 为什么要使用?
- 使用redux我们要实现视图的更新,需要先Store.getState()获取数据,使用Store.dispatch()更新数据,再使用Store.subscribe()去订阅这个更新,如果很多地方都这样做一遍,实在是不堪其重
- 换个思路,把store直接集成到React应用的顶层props里面,只要各个子组件能访问到顶层props就行了,Provider正是这样一个通过context设置store的组件,然后在通过connect容器组件把“指定的state & 指定的action”和 React组件关联起来
- Provider:将store传给组件
import { Provider } from 'react-redux' import store from './store' ReactDOM.render( <Provider store={store}> <App /> </Provider> , document.getElementById('root'));
- connect:将组件与redux关联起来的高阶函数
export default connect( mapStateToProps, mapDispatchToProps )(App);
- mapStateToProps():建立一个外部state到内部props的一个映射
- 是一个函数,接收state作为参数,返回一个对象,每一个key代表一个内部的属性
const mapStateToProps = (state) => { return { todos: getVisibleTodos(state.todos, state.visibilityFilter) } } //getVisibleTodos是一个自定义计算state的函数
- mapStateToProps会订阅 Store,每当state更新的时候,就会自动执行,重新计算 UI 组件的参数,从而触发 UI 组件的重新渲染。
- 可以接收第二个参数,代表容器组件的props值
const mapStateToProps = (state, ownProps) => { return { active: ownProps.filter === state.visibilityFilter } }
- 使用ownProps作为参数后,如果容器组件的参数发生变化,也会引发 UI 组件重新渲染。
- connect方法可以省略mapStateToProps参数,那样的话,UI 组件就不会订阅Store,就是说 Store 的更新不会引起 UI 组件的更新。
- 是一个函数,接收state作为参数,返回一个对象,每一个key代表一个内部的属性
- mapDispatchToProps():建立 UI 组件的参数到store.dispatch方法的映射
- 如果mapDispatchToProps是一个函数,会得到dispatch和ownProps(容器组件的props对象)两个参数。
const mapDispatchToProps = ( dispatch, ownProps ) => { return { onClick: () => { dispatch({ type: 'SET_VISIBILITY_FILTER', filter: ownProps.filter }); } }; }
- 也可以是一个对象
- 如果mapDispatchToProps是一个函数,会得到dispatch和ownProps(容器组件的props对象)两个参数。
- 两个函数都是将属性映射到props上面,所以通过this.props.onClick这样去取值