关于redux中的reducer的两点疑问

1、既然reducer强调不可变数据的概念为何不直接返回一个深拷贝之后的state,例如_.cloneDeep

2、既然不能直接更改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


www说
浏览 987回答 2
2回答

呼唤远方

问题1: 每次深拷贝是可以的,但是会浪费性能,因为不管你做了任何操作都会创立一个新的对象,特别是内容很多的对象,内存占用负担很大。问题2:你说的没错,就是可以用Object. freeze来保证immutable,这也是很多轻量级的immutable库内部的实现方式,可以看 seamless-immutable,immutable-helper这类库。题外话,immutable 保证了 reducer 在内部数据变化后,返回一个新对象,用处是判断两次数据时,只需要进行一次 reference 判断,而不用 deepEqual 判断,从而节省性能开销。

拉风的咖菲猫

不知道我跟你想的一不一样,可以看下combineReducers的源码:var hasChanged = false&nbsp; &nbsp; var nextState = {}&nbsp; &nbsp; for (var i = 0; i < finalReducerKeys.length; i++) {&nbsp; &nbsp; &nbsp; var key = finalReducerKeys[i]&nbsp; &nbsp; &nbsp; var reducer = finalReducers[key]&nbsp; &nbsp; &nbsp; var previousStateForKey = state[key]&nbsp; &nbsp; &nbsp; var nextStateForKey = reducer(previousStateForKey, action)&nbsp; &nbsp; &nbsp; if (typeof nextStateForKey === 'undefined') {&nbsp; &nbsp; &nbsp; &nbsp; var errorMessage = getUndefinedStateErrorMessage(key, action)&nbsp; &nbsp; &nbsp; &nbsp; throw new Error(errorMessage)&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; nextState[key] = nextStateForKey&nbsp; &nbsp; &nbsp; hasChanged = hasChanged || nextStateForKey !== previousStateForKey&nbsp; &nbsp; }&nbsp; &nbsp; return hasChanged ? nextState : state关键点在于每次reducer返回新的state会跟旧的state做===对比,如果false认为store改变,从而触发页面重绘,如果true,则认为不变,不会触发重绘。所以reducer返回新的state是为了通知redux让页面重绘。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript