Reactjs 如何将初始状态传递给减速器

Reactjs 如何将初始状态传递给减速器,reactjs,redux,graphql,Reactjs,Redux,Graphql,目前,我使用一个reducer创建了我的存储,该reducer将初始状态传递给它 import reducers from './reducers' const store = createStore( reducers, initialState, compose(...enhancers) ) // reducers.js export default function reducer(state, action) { console.log('stat

目前,我使用一个reducer创建了我的存储,该reducer将初始状态传递给它

import reducers from './reducers'

const store = createStore(
    reducers,
    initialState,
    compose(...enhancers)
  )


// reducers.js
export default function reducer(state, action) {
  console.log('state', state)
  switch (action.type) {
    case 'LOAD_UI':
      return Object.assign({}, state, {
        loadUI: action.loaded
      });
    case 'NO_MATCH':
      return Object.assign({}, state, {
        loadUI: true,
        isNoMatch: action.isNoMatch
      });
    default:
      return state;
  }
}
当我在reducer函数中使用记录状态时,我将获得配置存储时设置的状态:

// if we are in production mode, we get the initial state from the window object, otherwise, when we are in dev env we get it from a static file
const preloadedState = window.__INITIAL_STATE__ === '{{__PRELOADEDSTATE__}}' ? initialState : window.__INITIAL_STATE__

const store = configureStore(preloadedState)

ReactDOM.render(
  <Provider store={store}>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </Provider>
, document.getElementById('root')
)
所以我需要这样做:

const store = createStore(
    combineReducers({
      apollo: client.reducer(),
      reducer: reducers
    }),
    initialState,
    compose(...enhancers)
  )
import { combineReducers } from 'redux'
import { ApolloClient } from 'react-apollo';

const client = new ApolloClient();

import articles from './articles'
import pages from './pages'
import services from './services'
import clients from './clients'
import people from './people'
import offices from './offices'
import menus from './menus'
import settings from './settings'

export default combineReducers({
  apollo: client.reducer(),
  articles,
  pages,
  services,
  clients,
  people,
  offices,
  menus,
  settings
})
{
 loadUI: true
 isNoMatch: false
}
但是,我的reducer函数不再具有对state的访问权限(它是未定义的)。当我使用CombineReducer时,如何确保这一点得到通过

解决方案:

根据Daniel Rearden的建议,我需要将减速器的键与初始状态匹配

我的初始状态类似于:

{
  "pages": [
    {
      "id": 5,
      "title": "About",
      "slug": "about",
      "path": "/about",
      "template": "about",
      "published": "2017-07-10 02:02:30",
      "image": null,
      "seo": {
        "title": null,
        "description": null,
        "image": null,
        "fbAdmins": null,
        "gtm": null,
        "schema": ""
      },
      "sections": [
      ]
    },
    {
      "id": 10,
      "title": "Contact",
      "slug": "contact",
      "path": "/contact",
      "template": "contact",
      "published": "2017-07-11 04:27:30",
      "image": null,
      "seo": {
        "title": null,
        "description": null,
        "image": null,
        "fbAdmins": null,
        "gtm": null,
        "schema": ""
      },
      "sections": []
    },
    {
      "id": 4,
      "title": "Home",
      "slug": "home",
      "path": "/",
      "template": "home",
      "published": "2017-07-10 01:39:48",
      "image": null,
      "seo": {
        "title": null,
        "description": null,
        "image": null,
        "fbAdmins": null,
        "gtm": null,
        "schema": ""
      },
      "sections": []
    }
  ],
  "services": [],
  "clients": [],
  "people": [],
  "offices": [],
  "articles": [],
  "menus": {
    "header": [
      {
        "title": "Home",
        "slug": "/"
      },
      {
        "title": "About",
        "slug": "/about"
      },
      {
        "title": "Contact",
        "slug": "/contact"
      }
    ]
  },
  "settings": {
    "site": {
      "title": null,
      "siteUrl": ""
    },
    "logo": [],
    "secondarylogo": [],
    "favicon": [],
    "disclaimer": null,
    "tagline": null,
    "social": null,
    "email": null,
    "phone": null,
    "facebookAppId": "",
    "seo": {
      "title": null,
      "description": null,
      "image": null,
      "fbAdmins": null,
      "gtm": null,
      "schema": ""
    },
    "newsLetterSignUp": {
      "image": "",
      "title": "",
      "content": ""
    },
    "menu_settings": null
  }
}
我的减速机看起来像这样:

const store = createStore(
    combineReducers({
      apollo: client.reducer(),
      reducer: reducers
    }),
    initialState,
    compose(...enhancers)
  )
import { combineReducers } from 'redux'
import { ApolloClient } from 'react-apollo';

const client = new ApolloClient();

import articles from './articles'
import pages from './pages'
import services from './services'
import clients from './clients'
import people from './people'
import offices from './offices'
import menus from './menus'
import settings from './settings'

export default combineReducers({
  apollo: client.reducer(),
  articles,
  pages,
  services,
  clients,
  people,
  offices,
  menus,
  settings
})
{
 loadUI: true
 isNoMatch: false
}

因此,我的
页面
缩减器只获取我的初始状态的页面片段。

这不能像您预期的那样工作的原因是您更改了状态的结构,以及传递给原始缩减器的内容。在您的店铺出现之前:

const store = createStore(
    combineReducers({
      apollo: client.reducer(),
      reducer: reducers
    }),
    initialState,
    compose(...enhancers)
  )
import { combineReducers } from 'redux'
import { ApolloClient } from 'react-apollo';

const client = new ApolloClient();

import articles from './articles'
import pages from './pages'
import services from './services'
import clients from './clients'
import people from './people'
import offices from './offices'
import menus from './menus'
import settings from './settings'

export default combineReducers({
  apollo: client.reducer(),
  articles,
  pages,
  services,
  clients,
  people,
  offices,
  menus,
  settings
})
{
 loadUI: true
 isNoMatch: false
}
现在,您基本上已经告诉Redux要查找:

{
 apollo: {
   // ✁
 }
 reducers: {
   loadUI: true
   isNoMatch: false
 }
}
当您使用CombineReducer时,您实际上是在为您的状态创建隔离域,而不是将整个状态传递给每个reducer,redux将只将状态的一部分传递给每个reducer,并且reducer将只能更改该状态的一部分。通过如上所示构建存储,您已经告诉redux只将状态的
apollo
部分传递给apollo reducer。。。而
还原器
是原始还原器状态的一部分

我猜您没有对
预加载状态
进行任何更改。因此,redux正在
preforedState
中寻找一个名为
reducers
的属性,并将其传递给您的reducers。它找不到一个,所以它未定义地传入

这里最简单的修复方法是,首先,选择比
减缩器更具描述性的东西--
ui
?相应地更换组合减速器。然后更新您的
预加载状态
,以便您拥有的任何初始状态都嵌套在
ui
中。那么它应该像预期的那样工作。请记住,您还需要更新选择器和/或mapStateToProps函数


编辑:您可能想了解更多有关组合减速机工作原理的信息。

谢谢。这是值得一读的
组合减速机的工作原理。我忽略了一个事实,即每个reducer都映射到预加载状态中的一个键。