redux小记
Posted diyigechengxu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了redux小记相关的知识,希望对你有一定的参考价值。
Redux 设计和使用的三大原则:
1. 单一数据源:
一个应用永远只有唯一的数据源。使用单一数据源的好处在于整个应用状态都保存在一个对象中,这样我们随时可以 6提取出整个应用的状态进行持久化(比如实现一个针对整个应用的即时保存功能)。此外,这样 的设计也为服务端渲染提供了可能。工具函数combineReducers 可解决该数据源对象过于庞大的问题
2. 状态是只读的:
定义一个 reducer, 它的功能是根据当前触发的 action 对当前应用的状态(state)进行迭代,这里我们并没有直接修改应用的状态,而是返回了一份全新的状态。Redux 提供的 createStore 方法会根据 reducer 生成 store。最后,我们可以利用 store. dispatch方法来达到修改状态的目的。
3. 状态修改均由纯函数完成
Redux 利用每次新返回的状态生成酷炫的时间旅行(time travel)调试方式,让跟踪每一次因为触 发 action 而改变状态的结果成为了可能。
通过 createStore 方法创建的 store 是一个对象,包含以下方法。
? getState():获取 store 中当前的状态。
? dispatch(action):分发一个 action,并返回这个 action,这是唯一能改变 store 中数据的方式。
? subscribe(listener):注册一个监听者,它在 store 发生变化时被调用。
<Provider/> 接受一个 store 作为props,它是整个 Redux 应用的顶层组件,而 connect() 提供了在整个 React 应用的任意组件中获取 store 中数据的功能。
redux-middleware:
import compose from ‘./compose‘;
let newStore = applyMiddleware(mid1, mid2, mid3, ...)(createStore)(reducer, null);//创建一个普通的 store
export default function applyMiddleware(...middlewares) {//applyMiddleware 的结构也是一个多层 currying 的函数。借助 compose,applyMiddleware 可以用来和其他插件加强 createStore 函数:
return (next) => (reducer, initialState) => {
let store = next(reducer, initialState);//利用 createStore 和 reducer 创建了一个 store
let dispatch = store.dispatch;
let chain = [];
var middlewareAPI = {
getState: store.getState,
dispatch: (action) => dispatch(action),
};//store 的 getState方法和 dispatch 方法又分别被直接和间接地赋值给 middlewareAPI 变量 store
chain = middlewares.map(middleware => middleware(middlewareAPI));//middleware 带着 middlewareAPI 这个参数分别执行一遍。执行完后,获得 chain数组,保存的对象是第二个箭头函数返回的匿名函数
dispatch = compose(...chain)(store.dispatch);//将 chain 中的所有匿名函数,组装成一个新的函数,即新的 dispatch。当新 dispatch 执行时,数组内middleware从右到左依次执行
return { ...store,
dispatch,
};
}
}
logger middleware 的实现:
export default store => next => action => {//applyMiddleware 会对 logger 这 个 middleware 进行层层调用,动态地将 store 和 next 参数赋值。
console.log(‘dispatch:‘, action);
typeof action === ‘function‘ ? action(store.dispatch, store.getState) : next(action)//判断 action 是否是函数。如果是,则执行 action,否则继续传递 action 到下 一个 middleware。
console.log(‘finish:‘, action);
}
redux-saga: 采用generator,代替了async、await、promise等
react-router-redux:
对于前端应用来说,路由状态(当前切换到了哪个页面,当前页面的参数 有哪些,等等)也是应用状态的一部分。在很多情况下,我们的业务逻辑与路由状态有很强的关 联关系。比如,最常见的一个列表页中,分页参数、排序参数可能都会在路由中体现,而这些参 数的改变必然导致列表中的数据发生变化。因此,当我们采用 Redux 架构时,所有的应用状态必须放在一个单一的 store 中管理,路由 状态也不例外。而这就是 React Router Redux 为我们实现的主要功能。
对 Redux 的 store 进行一些增强,以便分发的 action 能被正确识别
import { browserHistory } from ‘react-router‘;
import { routerMiddleware } from ‘react-router-redux‘;
const middleware = routerMiddleware(browserHistory);
const store = createStore(
reducers,
applyMiddleware(middleware)
);
可以用 store.dispatch 来分发一个路由变动的 action 了:
import { push } from ‘react-router-redux‘;
// 切换路由到 /home store.dispatch(push(‘/home‘));
高阶 reducer 主要通过下面 3 点来增强reducer:高阶 reducer 就是指将 reducer 作为参数或者返回值的函数
? 能够处理额外的 action;
? 能够维护更多的 state;
? 将不能处理的 action 委托给原始 reducer 处理。
createStore 的函数签名:
export default function createStore(reducer, initialState, enhancer) { // ...}
createStore 中的第二个参数不仅扮演着 initialState 的角色。如 果我们传入的第二个参数是函数类型,那么 createStore 会认为你忽略了 initialState 而传入了 一个 enhancer。
如果我们传入了一个有效的enhancer,createStore会返回enhancer(createStore)(reducer, initialState) 的调用结果,这是常见的高阶函数调用方法。在这个调用中,enhancer 接受createStore 作为参数,
对 createStore 的能力进行增强,并返回增强后的 createStore。然后再 将 reducer 和 initialState 作为参数传给增强后的 createStore,最终得到生成的 store。
var currentReducer = reducer
var currentState = initialState
var listeners = []
var isDispatching = false
function getState() {
return currentState//getState 方法用于返回当前状态。
}
dispatch---将当前的状态和 action 传给当前的reducer,用于生成最新的 state。在得到新的状态后,依次调用所有的监听器,通知状态的变更。
需要注意的是,我们在通知监听器变更发生时,并没有将最新的状态作为参数传递给这些监听器。这是因为在监听器中,我们可以直接调用 store.getState() 方法拿到最新的状态。
React-Redux 将所有组件分成两大类:UI 组件(presentational component)和容器组件(container component)。
React-Redux 提供connect
方法,用于从 UI 组件生成容器组件。connect
的意思,就是将这两种组件连起来。
connect 函数本身返回名为 wrapWithConnect 的函数,而这个函数才是真正用来 装饰 React 组件的。而在我们装饰一个 React 组件时,
其实就是把组件在 Connect 类的 render 方 法中进行渲染,并获取 connect 中传入的各种额外数据。
connect 函数如果传入mapStateToProps,则会store.subscribe()监听state变化
Provider
在根组件外面包了一层,这样一来,App
的所有子组件就默认都可以拿到state
了。它的原理是React
组件的context
属性
class Provider extends Component {
getChildContext() {
return {store: this.props.store}
}
render() {
return this.props.children;
}
}
子组件就可以从context
拿到store
以上是关于redux小记的主要内容,如果未能解决你的问题,请参考以下文章
“ES7 React/Redux/GraphQL/React-Native 片段”不适用于 javascript 文件。除了安装它,我还需要配置其他东西吗?
react 中的 redux 和react-redux的区别分析