为了账号安全,请及时绑定邮箱和手机立即绑定

关于redux中的reducer的两点疑问

关于redux中的reducer的两点疑问

www说 2019-03-05 10:34:42
1、既然reducer强调不可变数据的概念为何不直接返回一个深拷贝之后的state,例如_.cloneDeep2、既然不能直接更改state,为何不利用Object.freeze,或者类似的方法让state不可改变import { SET_BOOKS, ADD_BOOK, REMOVE_BOOK, CHANGE_BOOK_PRICE } from '../actions/book.js'const initBooks = []const books = (state, action) => {    if (state === undefined) {        state = initBooks    }    //或者运用性能更好的_.cloneDeep    let tmpBooks = JSON.parse(JSON.stringify(state))    switch (action.type) {        case SET_BOOKS:            return action.books            break        case ADD_BOOK:            // return [...state,action.newBook]            tmpBooks.push(action.newBook)            return tmpBooks            break        case REMOVE_BOOK:            return state.filter(item => {                return item.id !== action.bookId            })            break        case CHANGE_BOOK_PRICE:            tmpBooks.forEach(item => {                if(item.id===action.bookId){                    item.price=action.newPrice                }            });            return action.books            break        default:            return state    }}export default books
查看完整描述

2 回答

?
呼唤远方

TA贡献1856条经验 获得超11个赞

问题1: 每次深拷贝是可以的,但是会浪费性能,因为不管你做了任何操作都会创立一个新的对象,特别是内容很多的对象,内存占用负担很大。
问题2:你说的没错,就是可以用Object. freeze来保证immutable,这也是很多轻量级的immutable库内部的实现方式,可以看 seamless-immutable,immutable-helper这类库。

题外话,immutable 保证了 reducer 在内部数据变化后,返回一个新对象,用处是判断两次数据时,只需要进行一次 reference 判断,而不用 deepEqual 判断,从而节省性能开销。


查看完整回答
反对 回复 2019-03-14
?
拉风的咖菲猫

TA贡献1995条经验 获得超2个赞

不知道我跟你想的一不一样,可以看下combineReducers的源码:


var hasChanged = false

    var nextState = {}

    for (var i = 0; i < finalReducerKeys.length; i++) {

      var key = finalReducerKeys[i]

      var reducer = finalReducers[key]

      var previousStateForKey = state[key]

      var nextStateForKey = reducer(previousStateForKey, action)

      if (typeof nextStateForKey === 'undefined') {

        var errorMessage = getUndefinedStateErrorMessage(key, action)

        throw new Error(errorMessage)

      }

      nextState[key] = nextStateForKey

      hasChanged = hasChanged || nextStateForKey !== previousStateForKey

    }

    return hasChanged ? nextState : state

关键点在于每次reducer返回新的state会跟旧的state做===对比,如果false认为store改变,从而触发页面重绘,如果true,则认为不变,不会触发重绘。所以reducer返回新的state是为了通知redux让页面重绘。


查看完整回答
反对 回复 2019-03-14
  • 2 回答
  • 0 关注
  • 986 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号