我正在尝试理解Dan Abramov发布的Redux在线教程.
目前我在以下样本:
目前我在以下样本:
Reducer composition with Arrays
以下是我在上面的示例后的练习代码:
// Individual TODO Reducer const todoReducer = (state,action) => { switch(action.type) { case 'ADD_TODO': return { id: action.id,text: action.text,completed: false }; case 'TOGGLE_TODO': if (state.id != action.id) return state; // This not working /* return { ...state,completed: !state.completed }; */ //This works var newState = {id: state.id,text: state.text,completed: !state.completed}; return newState; default: return state; } }; //TODOS Reducer const todos = (state = [],action) => { switch(action.type) { case 'ADD_TODO': return [ ...state,todoReducer(null,action) ]; case 'TOGGLE_TODO': return state.map(t => todoReducer(t,action)); default: return state; } }; //Test 1 const testAddTodo = () => { const stateBefore = []; const action = { type: 'ADD_TODO',id: 0,text: 'Learn Redux' }; const stateAfter = [{ id: 0,text: "Learn Redux",completed: false }]; //Freeze deepFreeze(stateBefore); deepFreeze(action); // Test expect( todos(stateBefore,action) ).toEqual(stateAfter); }; //Test 2 const testToggleTodo = () => { const stateBefore = [{id: 0,completed: false },{ id: 1,text: "Go Shopping",completed: false }]; const action = { type: 'TOGGLE_TODO',id: 1 }; const stateAfter = [{ id: 0,completed: true }]; //Freeze deepFreeze(stateBefore); deepFreeze(action); // Expect expect( todos(stateBefore,action) ).toEqual(stateAfter); }; testAddTodo(); testToggleTodo(); console.log("All tests passed");
问题是,在todoReducer函数中,以下语法不起作用:
return { ...state,completed: !state.completed };
我使用的是Firefox 44.0版,它在控制台中显示以下错误:
Invalid property id
现在我猜我当前版本的Firefox必须支持Spread操作符.
如果它不是,有没有办法添加一些独立的Polyfill来支持这种语法?
这里也是JSFiddle
解决方法
The object spread syntax is not supported in most browsers at the minute.建议在ES7(又名ES2016)中添加.据我所知,没有办法对它进行填充,因为它使用的是新语法,而不仅仅是函数调用.
在此期间您有两种选择.
1)使用Object.assign创建对象的更新版本,如下所示:
Object.assign({},state,{ completed: !state.completed });
虽然这也需要在大多数浏览器中填充 – @L_403_3@,或者您可以使用第三方库的版本,like the one in lodash.