javascript - Spread Operator 不适用于基于 Redux/ES6 的示例

标签 javascript ecmascript-6 redux polyfills spread-syntax

我正在尝试理解 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,
     text: "Learn Redux",
     completed: false
  }, {
    id: 1,
    text: "Go Shopping",
    completed: false
  }];

  const action = {
      type: 'TOGGLE_TODO',
      id: 1
  };

  const stateAfter = [{
     id: 0,
     text: "Learn Redux",
     completed: false
  }, {
    id: 1,
    text: "Go Shopping",
    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)中。据我所知,没有办法对其进行 polyfill,因为它使用了一种新的语法,而不仅仅是一个函数调用。

同时您有两个选择。

1) 使用 Object.assign 创建对象的更新版本,如下所示:

Object.assign({}, state, {
  completed: !state.completed
});

虽然这也需要在大多数浏览器中进行 polyfill - a good example one is available on MDN ,或者您可以使用第三方库的版本,like the one in lodash .

2) 使用像 Babel 这样的转译工具,它允许您使用更新的语法编写代码,然后将其转换为适用于所有浏览器的版本。

关于javascript - Spread Operator 不适用于基于 Redux/ES6 的示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35310830/

相关文章:

javascript - 带 Jest 的 vue-test-utils 为 map-spread 运算符抛出意外的 token 错误

javascript - mixin 中的initialState 是否与组件中的initialState 合并?

javascript - 如何修复 "dispatch is not a function"错误

ecmascript-6 - 如何修复嵌入模板上的任何指令未使用的属性绑定(bind) ng-forOf?

javascript - ReactJS:如何更改按钮单击时的文本值

react-native - 如何使用 React Native 和 Redux 获取 API 数据

reactjs - 使用大理石图运行测试时不会执行 ajax 请求

javascript - 如何在返回值之前等待其他事件完成?

javascript - 在内容可编辑的 DIV 中将 bb 代码包裹在选定的文本周围

javascript - 使用 mongoose 保存新数据时避免重复