简体   繁体   中英

Redux reducer to act on one node rather than whole store

I generally want my reducers to act on one node of the store. They take in one node and they return the new value of that node. That is how this one works (and it does work):

shape.reducer.js:

// @flow
import initialState from '../../config/config'

export const shape = (initialShape: string = initialState.get('shape'),
  action: Object): string => {
  switch (action.type) {
    case 'UPDATE_SHAPE': {
      const newShape = action.payload.value
      return newShape
    }
    default:
      return initialShape
  }
}

However, I am now working on a different app and writing my first reducer of the app. For some reason it is acting on the whole store:

keywords.reducer.js:

// @flow
import initialState from '../../config/config'

const keywords = (initialKeywords: string = initialState.get('searchForm').get('keywords'),
  action: Object): string => {
  switch (action.type) {
    case 'UPDATE_KEYWORDS': {
      const newKeywords = action.payload.value
      return newKeywords
    }
    default:
      return initialKeywords
  }
}

export default keywords

So for example if keywords gets updated to "word" then the whole store becomes just "word". The only difference between these two is how they are passed to createStore

top reducer:

const reducer = combineReducers({ height, width, thickness, shape })
const store = createStore(
  reducer,
  initialState,
  composeWithDevTools(applyMiddleware(thunk))
)

bottom reducer:

const store = createStore(
  keywords,
  initialState,
  devToolsEnhancer()
)

So I tried changing to this as it might stop it from acting on the whole store:

const reducer = combineReducers({ keywords })
const store = createStore(
  reducer,
  initialState,
  devToolsEnhancer()
)

but that caused this error:

Unexpected property "searchForm" found in previous state recieved by the reducer. Expected to find one of the known reducer property names instead: "keywords". Unexpected properties will be ignored.

By the way, this is my whole store when the app starts:

import { Map } from 'immutable'

const searchForm = Map(
  {
    'categories': ['meat'],
    'mealTypes': [],
    'location': {
      place: {},
      distanceFromPlaceValue: 10,
      distanceFromPlaceUnit: 'kilometer'
    },
    'keywords': ''
  }
)

const initialState = Map(
  {
    searchForm: searchForm
  }
)

export default initialState

You have set your initial store to an object which contains a key called searchForm in the below code

const initialState = Map(
  {
    searchForm: searchForm
  }
)

And in the reducer you are trying to set a reducer only for keywords . You should ideally use one reducer for each node in your state So you have to create 4 reducers and call it like below

const reducer = combineReducers({ keywords, categories , mealTypes, location })
const store = createStore(
  reducer,
  initialState,
  devToolsEnhancer()
)

And finally your initialState should be like below

const initialState = searchForm;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM