2017-05-20 1 views
2

J'apprends Redux à partir de ce tutorial et je ne comprends pas comment l'opérateur de propagation ci-dessous fonctionne à la fois dans l'objet et dans le tableau. Si ...state renvoie la même chose, comment cela peut-il fonctionner dans les deux situations? Je pensais que ça retournerait juste un tableau, donc ça marchera à l'intérieur du SHUTTER_VIDEO_SUCCESS parce qu'il va simplement propager tout ce qui est dans l'état dans le nouveau tableau en plus du action.videos, mais comment cela fonctionnera-t-il dans le cas SELECTED_VIDEO? Il n'y a pas de clé pour le placer. L'opérateur de propagation attrape le tableau pas la paire de valeurs de clé par défaut initialState?Comment fonctionne l'opérateur spread dans un tableau vs. obj?

initialState.js

export default { 
    images: [], 
    videos: [] 
}; 

someComponent.js

import initialState from './initialState'; 
import * as types from 'constants/actionTypes'; 

export default function (state = initialState.videos, action) { 
    switch (action.type) { 
    case types.SELECTED_VIDEO: 
     return { ...state, selectedVideo: action.video } 
    case types.SHUTTER_VIDEO_SUCCESS: 
     return [...state, action.videos]; 
    default: 
     return state; 
    } 
} 
+2

['...' n'est pas un opérateur!] (Https://stackoverflow.com/questions/37151966/what-is-spreadelement- in-ecmascript-documentation-is-it-the-same-as-spread-oper/37152508 # 37152508) –

Répondre

0

Un tableau est également une clé/valeur paire, mais la clé est un index. Il utilise ES6 destructuring et le spread syntax.

Redux docs on the subject

Vous pouvez également lire sur un raccourci de valeur de la propriété ES6 (ou peu importe son nom):

ES6 Object Literal in Depth

Chaque fois que vous vous trouvez attribuer une valeur de propriété qui correspond un nom de propriété, vous pouvez omettre la valeur de la propriété, il est implicite dans ES6.

+0

['...' n'est pas un opérateur!] (https://stackoverflow.com/questions/37151966/ Qu'est-ce-est-spreadelement-dans-ecmascript-documentation-is-it-the-same-as-spread-oper/37152508 # 37152508) –

+0

@FelixKling vous avez raison, l'a changé en "syntaxe de propagation", merci! N'a pas vraiment pensé à pourquoi je l'appelais opérateur, juste fait parce que beaucoup d'autres étaient. – rymdmaskin

+0

alors qu'est-ce que le 'SELECTED_VIDEO' retourne? comment l'état à l'origine d'un tableau se propage-t-il dans un objet?sera-t-il alors '{0: [...], selectedVideo: action.video}'? – stackjlei

0

Selon le tutoriel:

créer une réaction-application est préinstallée avec l'opérateur babel-plugin-transformation-objet reste répandue qui permet d'utiliser la diffusion (...) pour copier les propriétés énumérables d'un objet à l'autre d'une manière succincte. Pour le contexte, {... state, videos: action.videos} évalue à Object.assign ({}, state, action.videos).

Donc, ce n'est pas une caractéristique de ES6. Il utilise un plugin pour vous permettre d'utiliser cette fonctionnalité.

Lien: https://babeljs.io/docs/plugins/transform-object-rest-spread/

+0

vous avez abordé comment la syntaxe de propagation fonctionne avec les objets dans l'objet, mais ma question était de savoir comment cela fonctionne avec les tableaux dans un objet – stackjlei

+0

@stackjlei dans le cas SELECTED_VIDEO, un objet est retourné. –

4

MISE À JOUR

syntaxe de propagation vous permet de diffuser un tableau dans un objet (tableaux sont techniquement des objets, comme la plupart du temps tout en js). Lorsque vous répartissez un tableau dans un objet, il ajoute une paire key: value à l'objet pour chaque élément de tableau, où la clé est l'index et la valeur est la valeur stockée à cet index dans le tableau. Par exemple:

const arr = [1,2,3,4,5] 
const obj = { ...arr } // { 0: 1, 1: 2, 2: 3, 3: 4, 4: 5 } 

const arr2 = [{ name: 'x' }, { name: 'y' }] 
const obj2 = { ...arr2 } // { 0: { name: 'x' }, 1: { name: 'y' } } 

Vous pouvez également répartir des chaînes dans des tableaux et des objets.Pour les tableaux, il se comportera de la même que String.prototype.split:

const txt = 'abcdefg' 
const arr = [...txt] // ['a','b','c','d','e','f', 'g'] 

Pour les objets, il va diviser la chaîne par caractère et assigner des touches par index:

const obj = { ...txt } // { 0:'a',1:'b',2:'c',3:'d',4:'e',5:'f',6:'g' } 

Vous pouvez obtenir des données de ce genre d'œuvres lorsque vous répartissez un tableau dans un objet Cependant, si l'exemple que vous avez donné est ce que vous utilisez réellement, vous allez rencontrer des problèmes. Voir ci-dessous.

=============

Dans le cas des réducteurs dans Redux, lorsque vous utilisez la syntaxe de propagation avec un tableau, il se propage chaque élément de votre tableau dans un nouveau tableau. Il est fondamentalement la même que l'utilisation concat:

const arr = [1,2,3] 
const arr2 = [4,5,6] 
const arr3 = [...arr, ...arr2] // [1,2,3,4,5,6] 
// same as arr.concat(arr2) 

Avec un objet, la syntaxe de propagation se propage key: value paires d'un objet dans un autre:

const obj = { a: 1, b: 2, c: 3 } 
const newObj = { ...obj, x: 4, y: 5, z: 6 } 
// { a: 1, b: 2, c: 3, x: 4, y: 5, z: 6 } 

Ce sont deux façons de garder vos données immuables dans votre réducteurs. La syntaxe de propagation copie les éléments de tableau ou les clés/valeurs de l'objet plutôt que de les référencer. Si vous modifiez des objets imbriqués ou des objets dans des tableaux, vous devrez en tenir compte pour vous assurer d'obtenir de nouvelles copies plutôt que des données mutées. Si vous disposez de tableaux en tant que clés d'objet, vous pouvez répartir l'objet entier dans un nouveau, puis remplacer les clés individuelles selon les besoins, y compris les clés qui doivent être mises à jour avec la syntaxe de répartition. Par exemple, une mise à jour de votre exemple de code:

const initialState = { 
    images: [], 
    videos: [], 
    selectedVideo: '' 
} 

// you need all of your initialState here, not just one of the keys 
export default function (state = initialState, action) { 
    switch (action.type) { 
    case types.SELECTED_VIDEO: 
     // spread all the existing data into your new state, replacing only the selectedVideo key 
     return { 
     ...state, 
     selectedVideo: action.video 
     } 
    case types.SHUTTER_VIDEO_SUCCESS: 
     // spread current state into new state, replacing videos with the current state videos and the action videos 
     return { 
     ...state, 
     videos: [...state.videos, ...action.videos] 
     } 
    default: 
     return state; 
    } 
} 

Ceci affiche la mise à jour d'un objet d'état et des clés spécifiques de cet objet qui sont des tableaux.

Dans l'exemple que vous donnez, vous changez la structure de votre état à la volée. Il commence comme un tableau, puis retourne parfois un tableau (quand SHUTTER_VIDEO_SUCCESS) et parfois retourne un objet (quand SELECTED_VIDEO). Si vous voulez avoir une seule fonction de réduction, vous n'isoleriez pas votre initialState sur le seul tableau de vidéos. Vous devrez gérer l'ensemble de votre arborescence d'états manuellement comme indiqué ci-dessus. Mais votre réducteur ne devrait probablement pas changer le type de données qu'il renvoie en fonction d'une action. Ce serait un gâchis imprévisible.

Si vous voulez diviser chaque clé en un réducteur séparé, vous en auriez 3 (images, vidéos et vidéo sélectionnée) et utiliser combineReducers pour créer votre objet d'état.

import { combineReducers } from 'redux' 
// import your separate reducer functions 

export default combineReucers({ 
    images, 
    videos, 
    selectedVideos 
}) 

Dans ce cas, chaque réducteur sera exécuté chaque fois que vous envoyez une action pour générer l'objet état complet. Mais chaque réducteur ne traitera qu'avec sa clé spécifique, et non avec l'ensemble de l'objet d'état. Vous n'avez donc besoin que d'une logique de mise à jour de tableau pour les clés qui sont des tableaux, etc.

+0

['...' n'est pas un opérateur!] (Https://stackoverflow.com/questions/37151966/what-is-spreadelement-in-ecmascript-documentation-is-it-the-same-as-spread- oper/37152508 # 37152508) –

+0

Bien sûr. Édité pour mettre à jour à la syntaxe – shadymoses

+0

vous avez abordé comment la syntaxe de propagation fonctionne avec les tableaux dans le tableau et les objets dans l'objet, mais ma question était de savoir comment ça marche avec les tableaux dans un objet – stackjlei