Redux-管理预加载状态

Redux - managing preload state

本文关键字:状态 加载 管理 Redux-      更新时间:2023-09-26

我正在构建一个应用程序,其中我需要在应用程序启动时预加载peopleplanet数据(将来可能会添加更多的预加载要求)。我希望存储中的值表示应用程序的全局状态为loaded: <boolean>。只有当预加载要求people.loaded: trueplanet.loaded: true为真时,该值才会为真。商店看起来像这样:

Store
├── loaded: <Boolean>
├── people:
│   ├── loaded: <Boolean>
│   └── items: []
├── planets:
│   ├── loaded: <Boolean>
│   └── items: []

单独的操作创建者生成所需的异步请求和调度操作,这些操作由PeoplePlanets还原器处理。如下所示(使用redux thunk):

actions/index.js

import * as types from '../constants/action-types';
import {getPeople, getPlanets} from '../util/swapi';
export function loadPeople () {
  return (dispatch) => {
    return getPeople()
      .then((people) => dispatch(addPeople(people)));
  };
}
export function loadPlanets () {
  return (dispatch) => {
    return getPlanets()
      .then((planets) => dispatch(addPeople(planets)));
  };
}
export function addPeople (people) {
  return {type: types.ADD_PEOPLE, people};
}
export function addPlanets (planets) {
  return {type: types.ADD_PLANETS, planets};
}
export function initApp () {
  return (dispatch) => {
    loadPeople()(dispatch);
    loadPlanets()(dispatch);
  };
}

../util/swapi处理从LocalStorage获取人员和行星数据或发出请求。

initApp()动作创建者在渲染到DOM之前调用site.js中的其他动作创建者,如下所示:

site.js

import React from 'react';
import {render} from 'react-dom';
import Root from './containers/root';
import configureStore from './store/configure-store';
import {initApp} from './actions';
const store = configureStore();
// preload data
store.dispatch(initApp());
render(
  <Root store={store} />,
  document.querySelector('#root')
);

1.在Redux中管理应用程序全局预加载状态的最佳实践是什么

2.商店中是否需要全局loaded状态

3.在多个React组件中检查应用程序loaded状态的可扩展方式是什么对于只需要知道全局应用程序状态而不处理PeoplePlanets呈现的容器,包含PeoplePlanet状态似乎是不对的。此外,当多个容器中需要全局loaded状态时,管理起来也会很痛苦。


引用丹从Redux得到的部分答案——多家商店,为什么不呢?问题

使用reducer组合可以很容易地在Flux中实现"依赖更新"la waitFor,方法是编写一个reducer,手动调用具有附加信息的其他reducer并按特定顺序执行。

4.Dan调用其他减速器是否意味着调用嵌套的减速器

首先,让我纠正您的示例。

代替

export function initApp () {
  return (dispatch) => {
    loadPeople()(dispatch);
    loadPlanets()(dispatch);
  };
}

你可以(也应该)写

export function initApp () {
  return (dispatch) => {
    dispatch(loadPeople());
    dispatch(loadPlanets());
  };
}

您不需要将dispatch作为参数传递——thunk中间件会处理这一问题
当然,从技术上讲,你的代码是有效的,但我认为我的建议读起来更容易。


  1. 在Redux中管理应用程序全局预加载状态的最佳实践是什么

你所做的似乎是正确的。没有具体的最佳实践。

  1. 是否有必要在商店中设置全局加载状态

没有。正如大卫在回答中指出的,你们最好只存储必要的状态。

  1. 在多个React组件中检查应用程序加载状态的可扩展方式是什么?对于只需要知道全局应用程序状态并且不处理"人物"或"行星"渲染的容器,包含"人物"answers"行星"状态似乎是不对的。此外,当多个容器需要全局加载状态时,管理起来也会很痛苦

如果你担心重复,创建一个"选择器"函数,并将其放在你的减速器旁边:

// Reducer is the default export
export default combineReducers({
  planets,
  people
});
// Selectors are named exports
export function isAllLoaded(state) {
  return state.people.loaded && state.planets.loaded;
}

现在,您可以从组件导入选择器,并在任何组件内的mapStateToProps函数中使用它们:

import { isAllLoaded } from '../reducers';
function mapStateToProps(state) {
  return {
    loaded: isAllLoaded(state),
    people: state.people.items,
    planets: state.planet.items
  };
}
  1. Dan调用其他减速器是否意味着调用嵌套减速器

是的,reducer组合通常意味着调用嵌套的reducer
请参阅我的免费蛋头教程视频关于这个主题:

  • 带阵列的减速器组成
  • 减速器与物体的组合
  • combineReducers()还原剂组成
  • 从零开始实现combineReducers()

商店状态中加载的标志非常有意义。

然而,你已经有太多了。你有state.people.loadedstate.planets.loadedstate.loaded。后者源自前两者。你的商店真的不应该包含派生状态。要么只有前两个,要么只有后一个。

我的建议是保留前两个,即state.people.loadedstate.planets.loaded。然后,连接的组件可以导出最终加载状态。例如

function mapStateToProps(state) {
    return {
        loaded: state.people.loaded && state.planets.loaded,
        people: state.people.items,
        planets: state.planet.items
    };
}