Redux观点之二: Redux的三大原则

Redux里的倔强划定规矩与设想不少,大部分都邑与FP(函数式递次开辟)、革新底本的Flux架构设想有关。Redux官网文档上的三大基本原则,重要是由于有能够怕初学者不明白Redux中的一些限定或设想,所以先写出来申明,这内里也申清楚明了Redux的设想道理基本是怎样,所以强烈建议一切的初学者一定要彻底地明白这三大原则中的意义,多看几遍,对往后的进修会很有协助。以下离别申明,重要以原文的题目与内容申明,尽能够申明的比较清楚些。

单一原形泉源

你的全部运用中的state(状况),会存储在单一个store(存储)当中的一个对象树状构造里。

Redux中只要效单一个对象大树构造来的存储全部运用的状况,也就是全部运用中会用到的数据,称之为store(存储)。但要注重的是store(存储)并非只要纯真的数据罢了。store就是运用递次范畴的状况,它是范例MVC中的Model(模子的)设想的观点,这设想是由Flux架构而来的,在底本的Flux架构中是许可多个store的构造,Redux简化为只要单一个。

Redux的单一个store的设想有一些优点,对开辟者来讲,它能够轻易调试与视察状况的变化,状况存储于对象树状构造中,也很轻易作到重作/回复(Undo/Redo)的功用。由于只要一个store,但假如store里要储放多个差别的状况对象,以及每次的更动数据,天然就会变成了对象树状构造(object tree)。

另外,假如你想要从store中掏出现在的状况数据,能够用store的getState()要领。

状况是唯读的

唯一能更动状况的是发送一个action(行动),action是一个形貌”发作了什么事”的纯对象

这里指的”状况”,是上面说的储放在store中的状况数据,你”不能直接”对个中的状况数据更动,只能”间接”地作这事。这与本来的React中的statesetState的观点有点像,Redux的意义是你不能直接更动store内里所纪录的状况值,只能”间接”地透过发送action对象来叫store更动状况。”间接”地更动状况是一个很症结的设想,这是Flux中单向数据流的重点之一,这关于每一个行动发作,最终会影响到什么状况上的更动,一个接一个的递次等等的一种严厉的设想。

你能够会以为”状况既然是唯读”,直接与间接有什么差别,”唯读”不就代表完整不能更动,这语句是否是有误?

“唯读”固然就是完整不能更动的意义没错,所以状况对象的更动是并非在本来的状况对象上更改它,而是由本来状况对象由于行动的到场后,发生一个全新的状况对象,用这全新的状况对象来庖代本来的状况对象罢了。这在实在天下中也许很难拿比方来申明,但在软体天下中这很能够很轻易杀青。

“发作了什么事”这句,是代表每一个action都邑有一个type(范例),代表这个行动是要作什么用的,或是现在是发作了什么,比方是要新建一笔什么数据,或是删除全部数据等等,行动对象除了要申明它是要作什么以外,也须要包括所影响的数据。

发送一个action(行动),运用的是store.dispatch(action)语法款式,下面这个例子就是一个要更动状况的代码:

store.dispatch({
  type: 'COMPLETE_TODO',
  index: 1
})

中心的谁人纯对象,就叫作action(行动),它是一个纯真用于形貌发作了什么事与相干数据的纯对象:

{
  type: 'COMPLETE_TODO',
  index: 1
}

还记得我们在React中的statesetState要领的设想吗?state也是不能直接更动的,一定要透过setState要领才更动它。那这是为什么呢?由于setState不光只是更动state值,它还要作从新衬着的行动,React须要比对现在的状况,与即将要更改的状况,如许才进挪动新衬着的事情。Redux的设想中store是与React中的state比拟,它们之间有一些相似的设想。

更动只能由纯函数来举行

要指导状况树要怎样依actions(行动)来作转变,你须要撰写地道的归结函数(reducers)

Redux中的reducer的原型会长得像下面如许,你能够把它看成就是 之前的状况 + 行动 = 新的状况 的公式:

(previousState, action) => newState

注: 你能够参考Redux中Reducers这一章的内容,内里有实例。

不过,Redux中的reducer一定是纯函数(pure function),也就是不能有副作用的函数。因而由reducer所发生的新状况,并非直接修正之前的状况而来,而是一个复制之前状况,然后加上行动转变的部分,发生的一个新的对象,它如许设想是有缘由的。

Redux的store设想,并非底本Flux架构中的store,而是ReduceStore,这个ReduceStore是一个在Flux中的store进化版本,在申明中它有一个叫作reduce的要领,申明以下:

reduce(state: T, action: Object): T 归结(Reduces)现在的state(状况)与一个action(行动)到新的store中的state(状况)。一切的子类都须要实作这个要领。这个要领必需是地道而是无副作用。

那为什么要用这个进化的ReduceStore?它最后有申明一段:

不须要发送更动事宜注重一切继续自ReduceStore的store,不须要手动发送在reduce()中的更动事宜…state(状况)会自动地比对在每一个dispatch(发送)之前与以后,与自动地作发送更动事宜…

ReduceStore的设想与Redux最一开始的版本差不多是同时间宣布的,在开辟者之间相互有交换。Redux的store运用了相似于ReduceStore的设想,所以要更动Redux中的store,须要透过reducer,这是为了简化底本在Flux数据流的实作流程。

reducer在Redux中扮演了十分重要的症结角色,它是一种对store中所寄存的状况,要怎样因应差别的行动而举行革新的函数,而store也是由reducer所建立,比方像下面的代码:

// @Reducer
//
// action payload = action.text
// 运用地道函数的数组unshift,不能有副作用
// state(状况)一开始的值是空数组`state=[]`
function todoApp(state = [], action) {
  switch (action.type) {
    case 'ADD_ITEM':
      return [action.text, ...state]
    default:
      return state
  }
}

// @Store
//
// 由reducer建立store
const store = createStore(todoApp)

针对运用中差别功用的状况,能够离别写出差别的reducer,Redux中供应了combineReducers函数能够兼并多个reducer,比方以下的代码:

function todos(state = [], action) {
  switch (action.type) {
    case 'ADD_TODO':
      return state.concat([ action.text ])
    default:
      return state
  }
}

function counter(state = 0, action) {
  switch (action.type) {
    case 'INCREMENT':
      return state + 1
    case 'DECREMENT':
      return state - 1
    default:
      return state
  }
}

// rootReducer是个组合过的函数,
// 这里用的是对象属性初始设置简写法,
// combineReducers传参是一个对象
const rootReducer = combineReducers({
  todos,
  counter
})
    原文作者:eyesofkids
    原文地址: https://segmentfault.com/a/1190000008209999
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞