四十七----redux
一、redux
redux?于状态集中存储,状态的更新必须是?种可预测的?式更新。严格的单向数据流是Redux架构的设计核?。 这意味着应?中所有的数据都遵循相同的?命周期,这样可以让应?变得更加可预测且容易理解。
什么时候用redux?
- 多交互,多数据源等场景
- 某个组件的状态,需要共享
- 某个组件状态需要在任何地?都可以拿到
- ?个组件需要改变全局状态
- ?个组件需要改变另?个组件的状态
Redux之类的状态管 理库充当了?个应?的业务模型层,并不会受限于如React之类的View层。
1、redux三大原则 - 单?数据源整个应?的state 被储存在?棵object tree中,并且这个object tree只存在于唯??个 store中。这让同构应?开发变得?常容易。来?服务端的state可以在?需编写更多代码的情况下被 序列化并注?到客户端中。由于是单?的 state tree,调试也变得?常容易。在开发中,你可以把应 ?的state保存在本地,从?加快开发速度。此外,受益于单?的state tree ,以前难以实现的如“撤 销/重做”这类功能也变得轻?易举。
- State是只读的唯?改变state的?法就是触发action,action 是?个?于描述已发?事件的普通对 象。 这样确保了视图和?络请求都不能直接修改state,相反它们只能表达想要修改的意图。因为所 有的修改都被集中化处理,且严格按照?个接?个的顺序执?,因此不?担?竞争条件(race condition)的出现。 action 就是普通对象?已,因此它们可以被?志打印、序列化、储存、后期调 试或测试时回放出来。
- 使?纯函数来执?修改为了描述action 如何改变state tree ,你需要编写reducers。 Reducer只是? 些纯函数,它接收先前的state和action,并返回新的state。reducer主要是为了约束修改行为的,不让随便修改。刚开始你可以只有?个reducer,随着 应?变?,你可以把它拆成多个?的reducers,分别独?地操作state tree的不同部分,因为reducer 只是函数,你可以控制它们被调?的顺序,传?附加数据,甚?编写可复?的reducer来处理?些通 ?任务,如分?器。
redux使用示例:
import {
createStore } from 'redux';
/**
* 这是一个 reducer,形式为 (state, action) => state 的纯函数。
* 描述了 action 如何把 state 转变成下一个 state。
*
* state 的形式取决于你,可以是基本类型、数组、对象、
* 甚至是 Immutable.js 生成的数据结构。惟一的要点是
* 当 state 变化时需要返回全新的对象,而不是修改传入的参数。
*
* 下面例子使用 `switch` 语句和字符串来做判断,但你可以写帮助类(helper)
* 根据不同的约定(如方法映射)来判断,只要适用你的项目即可。
*/
function counter(state = 0, action) {
switch (action.type) {
case 'INCREMENT':
return state + 1;
case 'DECREMENT':
return state - 1;
default:
return state;
}
}
// 创建 Redux store 来存放应用的状态。
// API 是 { subscribe, dispatch, getState }。
let store = createStore(counter);
// 可以手动订阅更新,也可以事件绑定到视图层。
store.subscribe(() =>
console.log(store.getState())
);
// 改变内部 state 惟一方法是 dispatch 一个 action。
// action 可以被序列化,用日记记录和储存下来,后期还可以以回放的方式执行
store.dispatch({
type: 'INCREMENT' });
// 1
store.dispatch({
type: 'INCREMENT' });
// 2
store.dispatch({
type: 'DECREMENT' });
// 1
createStore:
Redux主要由三部分组成:store、reducer、action。Redux的核?就是 store,它有Redux提供的createStore函数?成,该函数返回3个处理函数getState,dispatch,subscribe。
export default function createStore() {
let state = {
} // 公共状态
const getState = () => {
} // 存储的数据,状态树;
const dispatch = () => {
} // 分发action,并返回?个action,这是唯?能改变
store中数据的?式;
const subscribe = () => {
} //注册?个监听者,store发?变化的时候被调?。
return {
dispatch,
subscribe,
getState
}
}
getState:
getState()实现 对象包含所有数据。如果想得到某个时点的数据,就要对Store?成快照。这种时点的数 据集合,就叫做State。
const getState = () => {
return state; }
dispatch
dispatch()的实现 直接修改state,state.num+‘a’,如修改state像这种情况,就会导致结果不是我们想要 的,后果可能很严重,如果避免呢? 如果可以随意修改state,会造成难以复现的bug ,我们需要实现有条件并且是具名修改的store数据,既然要分发action这?要传??个action对象,另外这对象包括我们 要修改的state和要操作的具名actionType,这??type属性值的不同来对state做相应的修改,代码如
下:
const dispatch = (action) => {
switch (action.type) {
case 'ADD':
return {
...state,
num: state.num + 1,
}
case 'MINUS':
return {
...state,
num: state.num - 1,
}
case 'CHANGE_NUM':
return {
...state,
num: state.num + action.val,
} // 没有匹配到的?法 就返回默认的值
default:
return state
}
}
从代码上看,这?并没有把action独?出来,接着往下看吧。 函数负责?成State。由于整个应?只有? 个 State对象,包含所有数据,对于?型应?来说,这个State必然?分庞?,导致 Reducer函数也?分 庞?。
reducer:
reducer是?个纯函数,它根据action和initState计算出新的state。
强制使?action来描述所有变化带来的好处是可以清晰地知道应?中到底发?了什么。如果?些东?改 变了,就可以知道为什么变。最后,为了把action和state串起来,就有了reducer。 reducer.js:
export default function reducer(action, state) {
//通过传进来的 action.type 让管理者去匹配要做的事情
switch (action.type) {
case 'ADD':
return {
...state,
num: state.num + 1,
}
case 'MINUS':
return {
...state,
num: state.num - 1,
}
case 'CHANGE_NUM':
return {
...state,
num: state.num + action.val,
} // 没有匹配到的?法 就返回默认的值
default:
return state
}
}
action:
Action是把数据从应?(译者注:这?之所以不叫view是因为这些数据有可能是服务器响应,?户输? 或其它?view的数据 )传到 store 的有效载荷。它是 store 数据的唯?来源。?般来说你会通过
store.dispatch() 将 action 传到store。
可以这样理解,Action 描述当前发?的事情。改变State 的唯?办法,就是使? Action。它会运送数据到 Store。
export const ADD = 'ADD'
export const MINUS = 'MINUS'
export const CHANGE_NUM = 'CHANGE_NUM'
/* * Action Creator 来?成action */
export function add(
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!