扩展运算符不适用于基于 Redux/ES6 的示例

Posted

技术标签:

【中文标题】扩展运算符不适用于基于 Redux/ES6 的示例【英文标题】:Spread Operator not working for Redux/ES6 based sample 【发布时间】:2016-05-20 13:07:21 【问题描述】:

我正在尝试了解 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

【问题讨论】:

为了完整性:... is not an operator! 【参考方案1】:

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

然后用 .babelrc 更新

“插件”:[“transform-object-rest-spread”]

【讨论】:

【参考方案2】:

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
);

尽管这在大多数浏览器中也需要填充 - a good example one is available on MDN,或者您可以使用第三方库的版本,like the one in lodash。

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

【讨论】:

ES2016 功能集被冻结,对象扩展语法不会成为其中的一部分 啊,我没有意识到这已经发生了。感谢您的信息!【参考方案3】:

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

https://babeljs.io/

【讨论】:

好的,那么我怎样才能将 Babel 与我提供的 JSFiddle 一起使用呢? [更新] 我想我已经在我的小提琴中添加了 babel.min.js 文件作为外部资源。但它仍然无法正常工作。 Babel 是您在命令行上/通过任务运行器运行的工具。您将无法将其包含在 jsFiddle 中。 @FaisalMq:你可以将 jsFiddle 的语言设置为 Bable。 @JoeClay:浏览器版本也可用。 我的错,我没有意识到 jsFiddle 支持它作为一种语法。曾经有一个浏览器版本可用,但现在已被弃用:babeljs.io/docs/usage/browser。但是,它们现在确实提供了指向第三方实现 (babel-standalone) 的链接。

以上是关于扩展运算符不适用于基于 Redux/ES6 的示例的主要内容,如果未能解决你的问题,请参考以下文章

运算符 = 不适用于 fstream

Flink Twitter Streaming示例不适用于自定义端点

基于身份的身份验证不适用于 Azure 存储文件共享

为啥析取赋值运算符 |= 不适用于布尔向量?

如何使用扩展运算符将对象数组推入特定元素

为啥 imagecreatefromjpeg 不适用于 .jpg 扩展名?