Spread Operator不适用于基于Redux / ES6的样本 [英] Spread Operator not working for Redux/ES6 based sample

查看:91
本文介绍了Spread Operator不适用于基于Redux / ES6的样本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



带数组的Reducer组合



这是我的练习代码,遵循以上示例:

  //单个TODO Reducer 
const todoReducer =(state,action)=> {
switch(action.type){
case'ADD_TODO':
return {
id:action.id,
text:action.text,
完成:false
};
case'TOGGLE_TODO':
if(state.id!= action.id)返回状态;

//这不起作用
/ *
返回{
...州,
已完成:!state.completed
};
* /

//这有效
var newState = {id:state.id,text:state.text,completed:!state.completed};
返回newState;
默认值:
返回状态;
}
};

// TODOS Reducer
const todos =(state = [],action)=> {
switch(action.type){
case'ADD_TODO':
return [
... state,
todoReducer(null,action)
]。
case'TOGGLE_TODO':
返回state.map(t => todoReducer(t,action));
默认值:
返回状态;
}
};

//测试1
const testAddTodo =()=> {
const stateBefore = [];

const action = {
类型:'ADD_TODO',
id:0,
text:'Learn Redux'
};

const stateAfter = [{
id:0,
text:Learn Redux,
completed:false
}];

//冻结
deepFreeze(stateBefore);
deepFreeze(动作);

//测试
expect(
todos(stateBefore,action)
).toEqual(stateAfter);
};

//测试2
const testToggleTodo =()=> {
const stateBefore = [{id:0,
text:Learn Redux,
completed:false
},{
id:1,
text:Go Shopping,
complete:false
}];

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

const stateAfter = [{
id:0,
text:Learn Redux,
completed:false
},{
id:1,
text:Go Shopping,
completed:true
}];

//冻结
deepFreeze(stateBefore);
deepFreeze(动作);

//预计
expect(
todos(stateBefore,action)
).toEqual(stateAfter);
};

testAddTodo();
testToggleTodo();
console.log(所有测试都通过);

问题是,在todoReducer函数中,以下语法不起作用:

 返回{
...州,
已完成:!state.completed
};

我使用的是Firefox 44.0版,它显示我在控制台中出现以下错误:

 无效的房产ID 

现在我猜我当前版本的Firefox必须支持Spread运营商。
如果它没有,有没有办法添加一些独立的Polyfill来支持这种语法?



这里也是 JSFiddle

解决方案

大多数浏览器不支持对象扩展语法。它建议在ES7(又名ES2016)中添加。据我所知,没有办法填充它,因为它使用新的语法而不仅仅是函数调用。



在此期间你有两个选择。 / p>

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

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

虽然这也需要在大多数浏览器中进行填充 - MDN上提供了一个很好的示例,或者您可以使用第三方库版本,喜欢lodash中的那个



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


I am trying to understand Redux online tutorials that are posted by Dan Abramov. At present I am on the following sample:

Reducer composition with Arrays

Here is my practice code following the above sample:

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

Issue is, within the todoReducer function, following syntax is not working:

return {
        ...state,
        completed: !state.completed
      };

I am using Firefox version 44.0 and it shows me following error in console:

Invalid property id

Now I guess my current version of Firefox must support Spread operator. If anyway it does not, is there any way to add some standalone Polyfill to support this syntax?

Here is also the JSFiddle

解决方案

The object spread syntax is not supported in most browsers at the minute. It's proposed for addition in ES7 (aka ES2016). As far as I know there's no way to polyfill it, as it uses a new syntax rather than just being a function call.

You have two options in the meantime.

1) Use Object.assign to create an updated version of the object, like so:

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

Although this will also need to be polyfilled in most browsers - a good example one is available on MDN, or you can use a third party library's version, like the one in lodash.

2) Use transpiling tools like Babel, which allow you to write your code with newer syntax and then convert it to a version that works in all browsers.

这篇关于Spread Operator不适用于基于Redux / ES6的样本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆