web-dev-qa-db-fra.com

React-Redux: Combinaison de réducteurs: Touches inattendues

Mon application fonctionne bien avant de commencer à combiner mes réducteurs Redux. Mais lorsque je combine, les clés initialState et réducteur sont mélangées.

function flash(state = [], action) {
  switch (action.type) {
  case FLASH_MESSAGE_UPDATED:
    return _.extend({}, state, { flash: action.flash })
  default:
    return state
  }
}

function events(state = [], action) {
  switch (action.type) {
  case EVENTS_UPDATED:
    return _.extend({}, state, { events: action.pathway_events })
  default:
    return state
  }
}

export default combineReducers({
  events,
  flash
})

Cela entraîne une fonctionnalité défectueuse et un erreur de la console sur:

Unexpected keys "one", "two" found in initialState argument passed to createStore. Expected to find one of the known reducer keys instead: "events", "flash". Unexpected keys will be ignored.

Mon état initial est transmis à l'aide de redux-thunk.

import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import reducer from '../../reducers/event'

let initialState = {
  one: globalData.one,
  two: globalData.two,
  events: globalData.events,
  flash: globalData.flash
}
let createStoreWithMiddleware = applyMiddleware(thunk)(createStore)
let reduxStore = createStoreWithMiddleware(reducer, initialState);

React.render(
  <Provider store={reduxStore}>
    <EventListContainer />
  </Provider>,
  $('.events')[0]
)

Comment puis-je combiner correctement les réducteurs?

46
steel

Je pense que vous devez simplement ajouter des réducteurs pour les clés supplémentaires, par exemple.

function one(state = {}, action) {
  switch (action.type) {
  case ONE_UPDATED:
    return action.one
  default:
    return state
  }
}

De les docs :

Si vous avez produit réducteur avec combineReducers, il doit s'agir d'un objet simple ayant la même forme que les clés qui lui ont été transmises. Sinon, vous êtes libre de passer tout ce que votre réducteur peut comprendre.

Si vous n’avez pas besoin de gérer d’actions liées à one ou two, commencez par les extraire au début, cela pourrait être aussi simple que

export default combineReducers({
  events,
  flash,
  one: (state = {}) => state,
  two: (state = {}) => state
})
61
nrabinowitz

tl; dr

Si vous effectuez une SSR, recompilez votre groupe côté serveur!

Explication

Ce message d'erreur peut apparaître lorsque vous effectuez un rendu côté serveur (SSR), modifiez quelque chose dans le code du réducteur et vous seulement recompilez/HMR du côté client .

Lorsque vous effectuez une SSR, vous devez sérialiser votre magasin Redux en une variable globale (comme window.__INITIAL_STATE__), donc lorsque vous initialisez le côté client, createStore peut le lire et créer le même état Redux.

Si vous ne recompilez pas votre code modifié pour le côté serveur, l'état initial du serveur peut toujours contenir un état avec les anciennes clés (à partir du anciens réducteurs) alors que le côté client a le nouvel état (à partir des nouveaux réducteurs/modifiés).

Techniquement, cela ne rompt pas le fonctionnement du côté client, car Redux ignore les clés inattendues. Il s’agit simplement d’un avertissement utile (pas vraiment une erreur) rappelant que vous devez recompiler votre paquet côté serveur. Cependant, cela peut poser un problème en production ou lorsque vous comparez les performances de hydratation car l'état différent peut entraîner un DOM différent. Bien entendu, cette erreur ne devrait pas se produire en production, car votre processus de déploiement devrait créer automatiquement à la fois les ensembles client et serveur.

9
totymedli