6

我正在尝试了解 Dan Abramov 发布的 Redux 在线教程。目前我在以下示例中:

使用数组的减速器组合

这是我在上述示例之后的练习代码:

// 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

4

3 回答 3

8

目前大多数浏览器都不支持对象扩展语法。它被提议在 ES7(又名 ES2016)中添加。据我所知,没有办法对其进行填充,因为它使用了一种新语法,而不仅仅是一个函数调用。

在此期间,您有两个选择。

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

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

尽管在大多数浏览器中这也需要进行填充——MDN上提供了一个很好的示例,或者您可以使用第三方库的版本,例如 lodash 中的版本。

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

于 2016-02-10T09:27:13.893 回答
2

如果使用 Babel 的人仍然遇到问题,此功能可能无法在 Babel 开箱后使用,您可能需要添加一个插件:http ://babeljs.io/docs/plugins/transform-object-rest-spread/

然后更新 .babelrc

“插件”:[“变换对象休息传播”]

于 2018-02-16T20:57:25.763 回答
1

你不能 polyfill 语法。如果您希望在当前浏览器中执行,则需要使用 babel 之类的东西来编译为旧版本的 JavaScript。

https://babeljs.io/

于 2016-02-10T09:27:21.977 回答