gpt4 book ai didi

javascript - 在 Redux Reducer 中读取 Store 的初始状态

转载 作者:IT王子 更新时间:2023-10-29 02:46:22 26 4
gpt4 key购买 nike

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

  • 将它作为第二个参数传递给 createStore ( docs link )
  • 将它作为第一个参数传递给你的(子)reducers(docs link)

  • 如果您将初始状态传递给您的商店,您如何从商店中读取该状态并将其作为 reducer 中的第一个参数?

    最佳答案

    TL;DR

    Without combineReducers() or similar manual code, initialState always wins over state = ... in the reducer because the state passed to the reducer is initialState and is not undefined, so the ES6 argument syntax doesn't get applied in this case.

    With combineReducers() the behavior is more nuanced. Those reducers whose state is specified in initialState will receive that state. Other reducers will receive undefined and because of that will fall back to the state = ... default argument they specify.

    In general, initialState 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.


    首先让我们考虑一个只有一个 reducer 的情况。
    说你不使用 combineReducers() .
    然后你的 reducer 可能看起来像这样:
    function counter(state = 0, action) {
    switch (action.type) {
    case 'INCREMENT': return state + 1;
    case 'DECREMENT': return state - 1;
    default: return state;
    }
    }
    现在假设您用它创建了一个商店。
    import { createStore } from 'redux';
    let store = createStore(counter);
    console.log(store.getState()); // 0
    初始状态为零。为什么?因为 createStore 的第二个参数是 undefined .这是 state第一次传递给你的 reducer 。当 Redux 初始化时,它会分派(dispatch)一个“虚拟” Action 来填充状态。所以你的 counter使用 state 调用 reducer 等于 undefined . 这正是“激活”默认参数的情况。 因此, state现在是 0根据默认 state值( state = 0)。将返回此状态 ( 0)。
    让我们考虑一个不同的场景:
    import { createStore } from 'redux';
    let store = createStore(counter, 42);
    console.log(store.getState()); // 42
    为什么是 42 , 而不是 0 , 这次?因为 createStore被调用 42作为第二个论点。该参数变为 state与虚拟 Action 一起传递给您的 reducer 。 这一次,state不是未定义的(它是 42 !),因此 ES6 默认参数语法无效。 state42 , 和 42从 reducer 返回。

    现在让我们考虑一个使用 combineReducers() 的情况。 .
    你有两个 reducer :
    function a(state = 'lol', action) {
    return state;
    }

    function b(state = 'wat', action) {
    return state;
    }
    combineReducers({ a, b })生成的reducer看起来像这样:
    // const combined = combineReducers({ a, b })
    function combined(state = {}, action) {
    return {
    a: a(state.a, action),
    b: b(state.b, action)
    };
    }
    如果我们调用 createStore没有 initialState ,它将初始化 state{} .因此, state.astate.b将是 undefined当它调用 a 时和 b reducer 。 两个ab reducer 将收到 undefined作为他们的state参数,如果他们指定默认 state值,那些将被返回。 这就是组合 reducer 返回 { 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() 的参数.从组合 reducer 返回的状态结合了我为 a 指定的初始状态带 'wat' 的 reducer 默认参数指定 b reducer 选择了自己。
    让我们回顾一下组合 reducer 的作用:
    // const combined = combineReducers({ a, b })
    function combined(state = {}, action) {
    return {
    a: a(state.a, action),
    b: b(state.b, action)
    };
    }
    在这种情况下, state已指定,因此它不会回退到 {} .它是一个带有 a 的对象字段等于 'horse' ,但没有 b field 。这就是为什么 a收到 reducer 'horse'作为它的 state并高兴地退回了它,但是 b收到 reducer undefined作为它的 state并因此返回了默认 state 的想法(在我们的示例中, 'wat')。这就是我们得到 { a: 'horse', b: 'wat' } 的方式作为返回。

    综上所述,如果你坚持 Redux 约定并在使用 undefined 调用 reducer 时从 reducer 返回初始状态。作为 state参数(实现这一点的最简单方法是指定 state ES6 默认参数值),您将对组合 reducer 有一个很好的有用行为。 他们会更喜欢 initialState 中的相应值。传递给 createStore() 的对象函数,但是如果你没有传递任何,或者没有设置对应的字段,默认state而是选择由 reducer 指定的参数。 这种方法效果很好,因为它提供了现有数据的初始化和水合,但是如果他们的数据没有被保留,它会让单个 reducer 重置他们的状态。当然,您可以递归地应用此模式,因为您可以使用 combineReducers()在许多层面上,甚至通过调用 reducer 并为它们提供状态树的相关部分来手动组合 reducer。

    关于javascript - 在 Redux Reducer 中读取 Store 的初始状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33749759/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com