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