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

2024-03-17

我目前使用一个减速器创建我的商店,该减速器已传递给它初始状态。

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;
  }
}

当我在减速器函数中记录状态时,我会得到配置商店时设置的状态:

// 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')
)

现在我想使用另一个减速器,因为我试图将 Apollo 包含在我的项目中。根据http://dev.apollodata.com/react/redux.html http://dev.apollodata.com/react/redux.html我需要结合Reducers:即

combineReducers({
    todos: todoReducer,
    users: userReducer,
    apollo: client.reducer(),
  }),

所以我需要做这样的事情:

const store = createStore(
    combineReducers({
      apollo: client.reducer(),
      reducer: reducers
    }),
    initialState,
    compose(...enhancers)
  )

但随后我的减速器函数不再有权访问状态(它是未定义的)。当我使用combineReducers时,如何确保它被传递?

解决方案:

根据 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
  }
}

所以我的减速器看起来像这样:

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
})

这样我的pages减速器仅获取我的初始状态的页面切片。


这没有按您预期的方式工作的原因是因为您改变了状态的结构以及传递给原始减速器的内容。以前你的商店看起来像这样:

{
 loadUI: true
 isNoMatch: false
}

现在,您基本上已经告诉 Redux 寻找:

{
 apollo: {
   // ✁
 }
 reducers: {
   loadUI: true
   isNoMatch: false
 }
}

当你使用combineReducers时,你本质上是在为你的状态创建隔离域——而不是将整个状态传递给每个reducer,redux只会将状态的一部分传递给每个reducer,并且reducer只能改变它状态切片。通过如上所示构造你的 store,你已经告诉 redux 仅传递apollo状态切片到 apollo 减速器......以及reducers原始减速器状态的一部分。

我猜你还没有做任何改变preloadedState。所以发生的事情是 redux 正在寻找一个属性preloadedState called reducers并将其传递给您的减速器。它找不到一个,所以它传递的是未定义的。

这里最简单的解决方法是,首先,选择比reducers -- ui或许?相应地更改您的combineReducers。然后更新你的preloadedState这样无论你有什么初始状态都嵌套在里面ui。然后它应该按预期工作。请记住,您还需要更新选择器和/或 mapStateToProps 函数!

Edit:您可能想了解更多有关combineReducers如何工作的信息here http://redux.js.org/docs/recipes/reducers/UsingCombineReducers.html.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何将初始状态传递给减速器 的相关文章

随机推荐

  • 如何在ng bootstrap的输入中设置日期格式

    我在用NG引导程序 https ng bootstrap github io components datepicker日期选择器 我想在输入标签中设置日期格式 这是我的html代码
  • 将盲文字符打印到 cmd c++

    对于一个程序 我需要将盲文字符输出到控制台 我找到了一种使用如下代码输出 unicode 字符的方法 include
  • onCreateDrawableState 永远不会调用

    我必须向RelativeLayout 添加新状态 但永远不会调用onCreateDrawableState 方法 我的班级是 public class UnreadableRelativeLayout extends RelativeLay
  • java.lang.ClassCastException:无法转换 java.util.LinkedHashMap

    javascript ajax headers Accept application json Content Type application json url realgrid product addOd do type post da
  • SqlDataAdapter.Fill() 超时 - 底层存储过程快速返回

    我有一个 SqlDataAdapter 其中填充了 21 行数据 4 列 驱动它的存储过程会在几秒钟内返回 SQL Mgmt Studio 但 Fill 需要 5 分钟 ArrayList ret new ArrayList SqlData
  • iOS - CALayer 和手势/滑动识别器

    我在视图中添加了一个图层来创建渐变背景色 但我需要使用UISwipeGestureRecognizer在我看来 问题是 现在有了图层 滑动识别器就不起作用了 我能怎么做 我可以向图层添加滑动识别器吗 谢谢 CALayer及其孩子不支持UIG
  • 对象字面量中的括号

    对象字面量中的括号只是分组运算符吗 节点字符串化 https github com fuqcool node stringify将转换 a 1 到字符串 a 1 a 2 我是否可以认为这里的括号对数据没有影响 即即使没有括号也完全相同 Ye
  • 最小宽度媒体查询在 ipad 上不起作用?

    为什么在横向模式下的 iPad 上无法拾取以下媒体查询 media all and min device width 1000px css here Or media all and min width 1000px css here 我希
  • Django:无法将关键字“”解析为字段。选项有:

    我在访问时遇到这个奇怪的问题ManyToManyField 我有以下型号 class Link models Model title models CharField max length 200 url models URLField u
  • 将 uri 传递给另一个 Activity 并将其转换为图像

    如何发送uri图像到另一个活动的路径并将其转换为图像 我尝试了下面的 protected void onActivityResult int requestCode int resultCode Intent data super onAc
  • 使用 SQL 和 PHP 将数据从页面传递到引导模式

    因此 根据标题 我尝试在引导模式上使用 sql 来传递显示数据库中的多个数据 ID会从链接中传递下来 是怎么做到的呢 一直在寻找多种方法 但我仍然无法显示所选数据 所以这是模式的触发器 tr td style text align cent
  • VB6在制作exe文件时冻结

    我正在用 VB6 编写一个项目 我使用的是 Win7 32 位 项目有问题 这个项目是很多年前写的 现在我正在重新编译它 当我发出 Make xxx exe 命令时 VB6 开始编译并冻结 还创建了超过 10 000 个 tmp 文件 几分
  • android livedata进行顺序调用

    我正在使用改造 实时数据 我的项目中有一种情况 我必须进行网络调用的顺序 如果任何一个失败 它应该返回错误 目前我有两个实时数据观察者来完成工作 这不是一个好的方法 所以我想知道更好的方法或示例代码来处理这种需求 注意 我没有使用 Rxja
  • C++ std::function 找不到正确的重载

    考虑以下情况 void Set const std function
  • VS 2017 颜色主题编辑器 - 如何更改 Intellisense 自动完成背景颜色

    我已使用颜色主题编辑器导入了透明主题 并且正在尝试更改自动完成框的背景颜色 目前 如下所示 它是透明的 并且很难阅读下面几行的文本 我尝试了多种元素 但找不到合适的元素 谷歌一无所获 如何更改自动完成 智能感知自动完成框背景颜色 将树视图背
  • 在pandas中,如何找到累积和大于阈值的行/索引?

    我想找到某列中的值的累积和超过阈值的行 索引 我可以并且确实使用一个简单的循环找到这个位置 如下所示 def sum to df col threshold s 0 for r in df iterrows if s r 1 col gt
  • 如何使 pdb 识别出运行之间的源已更改?

    据我所知 pdb 无法识别源代码在 运行 之间何时发生更改 也就是说 如果我正在调试 注意到一个错误 修复该错误 然后在 pdb 中重新运行程序 即不退出 pdb pdb 将不会重新编译代码 即使 pdb 列出了新的源代码 我仍然会调试旧版
  • 谁在我的类中调用 PaintComponent() 方法?

    我有一个简单的类 可以在 JPanel 中绘制图形 这是我的课 import java awt Color import java awt Dimension import java awt Graphics import javax sw
  • 使用 ARKit 拍摄高质量照片

    我对使用 ARKit 跟踪手机位置以使用相机自动拍照的功能感兴趣 我的初步调查让我了解到 虽然 ARKit 使用相机 但使用标准 AVFoundation 方法不可能获得高质量图像 由于正在使用相机 我明白我可以使用sceneView sn
  • 如何将初始状态传递给减速器

    我目前使用一个减速器创建我的商店 该减速器已传递给它初始状态 import reducers from reducers const store createStore reducers initialState compose enhan