2016-02-10 6 views
6

Ich versuche Redux Online-Tutorials zu verstehen, die von Dan Abramov gepostet werden. Derzeit bin ich auf folgendes Beispiel:Spread Operator funktioniert nicht für Redux/ES6-basiertes Beispiel

Reducer composition with Arrays

Hier ist meine Praxis Code nach dem obigen Beispiel:

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

Ausgabe ist, innerhalb der todoReducer Funktion, Syntax folgenden nicht funktioniert:

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

ich bin mit Firefox ab Version 44.0 und es zeigt mir folgende Fehler in der Konsole:

Invalid property id 

Jetzt denke ich, meine aktuelle Version von Firefox muss Spread-Operator unterstützen. Wenn dies nicht der Fall ist, gibt es eine Möglichkeit, einige eigenständige Polyfill hinzuzufügen, um diese Syntax zu unterstützen?

Hier ist auch die JSFiddle

+0

Der Vollständigkeit halber: [! '...' kein Operator ist] (https://stackoverflow.com/questions/37151966/what -ist-spreadelement-in-ecmascript-Dokumentation-is-it-the-sam e-as-spread-oper/37152508 # 37152508) –

Antwort

7

The object spread syntax is not supported in most browsers at the minute. Es wird für die Hinzufügung in ES7 (aka ES2016) vorgeschlagen. Soweit ich weiß, gibt es keine Möglichkeit, es zu füllen, da es eine neue Syntax verwendet und nicht nur ein Funktionsaufruf ist.

Sie haben in der Zwischenzeit zwei Möglichkeiten.

1) Object.assign Verwenden Sie eine aktualisierte Version des Objekts zu erstellen, etwa so:

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

Obwohl dies auch in den meisten Browsern polyfilled werden müssen - a good example one is available on MDN, oder Sie können eine dritte Partei Bibliothek Version verwenden , like the one in lodash.

2) Verwenden Sie transpilierende Tools wie Babel, mit denen Sie Ihren Code mit neueren Syntax schreiben und dann in eine Version konvertieren können, die in allen Browsern funktioniert.

+3

ES2016 Feature-Set ist eingefroren und Objektspreizsyntax wird kein Teil davon sein – vkurchatkin

+1

Ah, ich wusste nicht, dass das schon passiert ist. Danke für die Information! –

1

Sie können Syntax nicht polyfill. Sie müssen etwas wie babel verwenden, um eine ältere Version von JavaScript zu kompilieren, wenn Sie in aktuellen Browsern ausgeführt werden möchten.

https://babeljs.io/

+0

OK, also wie kann ich Babel zusammen mit meinem mitgelieferten JSFiddle benutzen? [UPDATE] Ich denke, ich habe bereits babel.min.js Datei als externe Ressource in meiner Geige hinzugefügt. Aber es funktioniert immer noch nicht. –

+1

Babel ist ein Tool, das Sie in der Befehlszeile/durch einen Task-Runner ausführen. Sie können es nicht in ein jsFiddle aufnehmen. –

+2

@FaisalMq: Sie können die Sprache von jsFiddle auf Bable setzen. –

0

Wenn jemand mit Babel noch Schwierigkeiten haben wird, ist diese Funktion mit Babel aus der Box nicht verfügbar sein, Sie ein Plugin hinzufügen müssen können: http://babeljs.io/docs/plugins/transform-object-rest-spread/

dann aktualisieren .babelrc mit

"Plugins": [ "Transform-Objekt-rest-Spread"]