2016-02-10 15 views
6

Sto cercando di capire le esercitazioni online di Redux pubblicate da Dan Abramov. Al momento sono sul seguente esempio:Operatore di diffusione che non funziona per l'esempio basato su Redux/ES6

Reducer composition with Arrays

Ecco il mio codice pratica seguendo l'esempio di cui sopra:

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

problema è, all'interno della funzione todoReducer, sintassi seguente non funziona:

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

sto usando Firefox versione 44.0 e mi mostra seguente errore in console:

Invalid property id 

Ora suppongo che la mia versione corrente di Firefox debba supportare l'operatore di Spread. Se in ogni caso no, c'è un modo per aggiungere del Polyfill standalone per supportare questa sintassi?

Anche qui è la JSFiddle

+0

Per completezza: [! '' ... non è un operatore] (https://stackoverflow.com/questions/37151966/what -is-spreadelement-in-ECMAScript documentazione-è-da-il-sam e-as-spread-oper/37152508 # 37152508) –

risposta

7

The object spread syntax is not supported in most browsers at the minute. Viene proposto per l'aggiunta in ES7 (aka ES2016). Per quanto ne so, non c'è modo di aggiungerlo in polifibrio, poiché utilizza una nuova sintassi anziché essere semplicemente una chiamata di funzione.

Nel frattempo hai due opzioni.

1) Utilizzare Object.assign per creare una versione aggiornata di un oggetto, in questo modo:

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

Anche se questo dovrà anche essere polyfilled nella maggior parte dei browser - a good example one is available on MDN, oppure è possibile utilizzare la versione di una libreria di terze parti , like the one in lodash.

2) Utilizzare strumenti di transpillazione come Babel, che consentono di scrivere il codice con la sintassi più recente e quindi convertirlo in una versione che funziona in tutti i browser.

+3

Il set di funzionalità ES2016 è bloccato e la sintassi di diffusione degli oggetti non ne farà parte. – vkurchatkin

+1

Ah, non mi ero reso conto che fosse già successo. Grazie per le informazioni! –

1

Non è possibile la sintassi di polyfill. È necessario utilizzare qualcosa come babel per compilare una versione precedente di JavaScript se si desidera eseguire nei browser correnti.

https://babeljs.io/

+0

OK, quindi come posso utilizzare Babel insieme al mio JSFiddle in dotazione? [AGGIORNAMENTO] Credo di aver già aggiunto il file babel.min.js come risorsa esterna nel mio violino. Ma non funziona ancora. –

+1

Babel è uno strumento che si esegue sulla riga di comando/tramite un task runner. Non sarai in grado di includerlo in un jsFiddle. –

+2

@FaisalMq: puoi impostare la lingua di jsFiddle su Bable. –

0

Se qualcuno utilizza Babel è ancora problemi, questa funzione potrebbe non essere disponibile con Babel, fuori dalla scatola, potrebbe essere necessario aggiungere un plugin: http://babeljs.io/docs/plugins/transform-object-rest-spread/

quindi aggiornare .babelrc con

"plugins": [ "trasformare-oggetto-resto-diffusione"]