Redux应用程序中的初始状态可以通过两种方式设置:

  • 将其作为第二个参数传递给createStore(docs link)
  • 将其作为第一个参数传递给(子)还原器(docs link)

如果将初始状态传递给存储,如何从存储中读取该状态,并使其成为还原器中的第一个参数?

推荐答案

TL;博士

如果没有combineReducers()或类似的手动代码,initialState在reducer中总是胜过state = ...,因为state传递给reducer is initialStateis not undefined,所以ES6参数语法不适用于这种情况.

combineReducers()岁时,行为更加微妙.initialState中规定状态的减速器将收到state.其他减速器将接收undefined and because of that,并返回到它们指定的默认参数state = ....

In general, 100 wins over the state specified by the reducer. This lets reducers specify initial data that makes sense to them as default arguments, but also allows loading existing data (fully or partially) when you're hydrating the store from some persistent storage or the server.

First let's consider a case where you have a single reducer.
Say you don't use combineReducers().

那么你的减速器可能是这样的:

function counter(state = 0, action) {
  switch (action.type) {
  case 'INCREMENT': return state + 1;
  case 'DECREMENT': return state - 1;
  default: return state;
  }
}

现在假设你用它创建了一个store .

import { createStore } from 'redux';
let store = createStore(counter);
console.log(store.getState()); // 0

初始状态为零.为什么?因为createStore的第二个参数是undefined.这是第一次传递给减速器的state.当Redux初始化时,它会发送一个"虚拟"操作来填充状态.所以你的counter减速机被称为state等于undefined.This is exactly the case that “activates” the default argument.因此,根据默认的state值(state = 0),state现在是0.将返回此状态(0).

让我们考虑另一种情况:

import { createStore } from 'redux';
let store = createStore(counter, 42);
console.log(store.getState()); // 42

为什么这次是42,而不是0?因为createStore是以42作为第二个参数调用的.此参数将与伪操作一起传递给减速机.This time, 104 is not undefined (it's 100!), so ES6 default argument syntax has no effect. state4242从减速器返回.


Now let's consider a case where you use combineReducers().
You have two reducers:

function a(state = 'lol', action) {
  return state;
}

function b(state = 'wat', action) {
  return state;
}

combineReducers({ a, b })生成的减速器如下所示:

// const combined = combineReducers({ a, b })
function combined(state = {}, action) {
  return {
    a: a(state.a, action),
    b: b(state.b, action)
  };
}

如果我们在没有initialState的情况下调用createStore,它将初始化state{}.因此,当它调用ab减速机时,state.astate.b将是undefined.Both 107 and 108 reducers will receive 106 as their 102 arguments, and if they specify default 102 values, those will be returned.这就是组合减速器在第一次调用时返回{ a: 'lol', b: 'wat' }状态对象的方式.

import { createStore } from 'redux';
let store = createStore(combined);
console.log(store.getState()); // { a: 'lol', b: 'wat' }

让我们考虑另一种情况:

import { createStore } from 'redux';
let store = createStore(combined, { a: 'horse' });
console.log(store.getState()); // { a: 'horse', b: 'wat' }

现在我指定initialState作为createStore()的参数.从组合减速器combines返回的状态是我为a减速器指定的初始状态,'wat'默认参数指定b减速器自行 Select .

让我们回忆一下组合减速器的功能:

// const combined = combineReducers({ a, b })
function combined(state = {}, action) {
  return {
    a: a(state.a, action),
    b: b(state.b, action)
  };
}

在本例中,指定了state,因此它不会回落到{}.这是一个a场等于'horse'场的物体,但没有b场.这就是为什么a减速机收到'horse'作为其state并愉快地返回它,但b减速机收到undefined作为其state,因此返回默认state中的its idea(在我们的示例中为'wat').这就是我们得到回报的方式.


综上所述,如果您坚持Redux约定,并在使用undefined作为state参数调用减缩器时从减缩器返回初始状态(实现这一点的最简单方法是指定state ES6默认参数值),那么对于组合减缩器,您将有一个非常有用的行为.They will prefer the corresponding value in the 103 object you pass to the 104 function, but if you didn't pass any, or if the corresponding field is not set, the default 101 argument specified by the reducer is chosen instead.这种方法工作得很好,因为它提供了现有数据的初始化和水合作用,但如果数据未被保留,则允许单个还原程序重置其状态.当然,您可以递归地应用此模式,因为您可以在许多级别上使用combineReducers(),甚至可以通过调用reducer并为它们提供状态树的相关部分来手动编写reducer.

Reactjs相关问答推荐

useReducer和带有回调的useState之间是否有实际区别?

避风港访问端口以包含Reaction应用程序

导致useState中断的中断模式

如何通过回调函数获取多个值?

MUiv5和TSS-Reaction SSR问题:无法可靠地处理样式定义.CSSprops 中的ArrowFunctionExpression

如何在REACTIVE js中动态添加或删除输入字段?

我如何在不被 destruct 的情况下将导航栏固定在顶部?

如何使ionic 面包屑在州政府条件下可点击?

阻止组件更新的多分派Redux Thunk或setState是否有任何问题

Javascript - 正则表达式不适用于 MAC OS - 编码?

当从子状态更改复制时,react 父状态更改.我该如何防止这种情况?

如何在不同的路由中渲染相同的页面组件(包括 getServerSideProps)

如何解决使用react-hook-form和yup动态创建的输入不集中的问题

在MongoDB中,如何获取最后N条记录中字段不为空或不为空字符串的数据

useState 在生命周期中的位置

用 jest 测试包裹在 redux 和 router 中的组件

如何使用react 路由将 url 参数限制为一组特定的值?

为什么我在运行一些 npm react 命令时会收到这些警告?

为什么 React 会多次调用我的应用程序的某些函数?

React LinkProps 的含义