Spread Operator не работает для примера на основе Redux/ES6

Я пытаюсь понять онлайн-учебники 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

3 ответа

Решение

Синтаксис распространения объекта в настоящее время не поддерживается большинством браузеров. Предлагается для добавления в ES7 (он же ES2016). Насколько я знаю, нет способа его заполнить, так как он использует новый синтаксис, а не просто вызов функции.

Тем временем у вас есть два варианта.

1) Использование Object.assign создать обновленную версию объекта, вот так:

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

Хотя в большинстве браузеров это также необходимо будет заполнить - хороший пример доступен в MDN, или вы можете использовать версию сторонней библиотеки, например, в lodash.

2) Используйте инструменты транспонирования, такие как Babel, которые позволяют писать код с более новым синтаксисом, а затем преобразовывать его в версию, которая работает во всех браузерах.

Если у кого-то, использующего Babel, все еще возникают проблемы, эта функция может быть недоступна с Babel "из коробки", вам может потребоваться добавить плагин: http://babeljs.io/docs/plugins/transform-object-rest-spread/

затем обновите.babelrc

"plugins": ["transform-object-rest-spread"]

Вы не можете polyfill синтаксис. Вам нужно использовать что-то вроде babel для компиляции в более старую версию JavaScript, если вы хотите выполнить в текущих браузерах.

https://babeljs.io/

Другие вопросы по тегам