【问题标题】:Where should I load data from server in Redux + ReactJS?我应该在 Redux + ReactJS 中从服务器加载数据到哪里?
【发布时间】:2017-06-19 01:59:21
【问题描述】:

例如,我有两个组件 - ListOfGroupsPage 和 GroupPage。

在 ListOfGroupsPage 中,我从服务器加载组列表并将其存储到 state.groups

在路线中,我为 GroupPage 提供了类似“group/:id”的映射

加载此地址后,应用程序显示 GroupPage,在这里我从 state.groups 获取组的数据(尝试通过 id 查找 state 中的组)。 一切正常。

但是如果我重新加载页面,我仍然在页面 /group/2 上,因此会显示 GroupPage。但是状态是空的,所以应用找不到组。

在 React + Redux 中加载数据的正确方法是什么?我可以这样看:

1) 加载根组件中的所有数据。交通方面的开销会很大

2) 不要依赖 store,尝试在每个组件上加载所需的数据。这是更安全的方式。但我不认为为每个组件加载相同的数据 - 这是一个很酷的想法。那么我们就不需要状态了——因为每个组件都会从服务器获取数据

3) ???可能会在每个组件中添加某种检查 - 首先尝试在存储中找到所需的数据。如果不能 - 从服务器加载。但它需要每个组件中的大量逻辑。

那么,在使用 Redux + ReactJS 的情况下,是否有从服务器获取数据的最佳解决方案?

【问题讨论】:

    标签: reactjs redux react-redux react-router-redux


    【解决方案1】:

    我建议使用localstorage 缓存客户端上的信息。将您的 Redux 状态或其中的重要部分持久保存到 localstorage 以进行状态更改,并在加载时检查 localstorage 中的现有记录。由于数据将在客户端上,因此检索起来会简单快捷。

    【讨论】:

    • 但是如果localstorage是空的怎么办?
    • 我的意思是,我支持 state.groups 到本地存储。然后用户出于某种原因清理存储。更新页面并收到类似“无法获取未定义组”的错误
    • 然后进行 AJAX 调用作为应急计划。 localstorage 很少被普通用户清除,但是每隔一段时间向您的后端发送一些 HTTP 请求不会让您的情况比以前更糟。
    【解决方案2】:

    我的方法是在商店创建后直接从服务器获取。我通过调度动作来做到这一点。我还使用 thunk 在*_REQUEST 上设置isFetching = true,并在*_SUCCESS*_FAILURE 之后将其设置回false。这允许我向用户显示进度条或微调器等内容。我认为您可能高估了“流量”问题,因为只要您以一种在商店的特定部分为空时不会中断的方式构建组件,它将异步执行。

    您看到的“无法获得未定义组”的问题(您在评论中提到)可能是因为您有一个对象并且正在对它执行.groups。该对象很可能是空的,因为它尚未被填充。这里有几件事需要考虑:

    • 在组件中使用三元运算符来检查someObject.groups 是否为空;或
    • 在 initialState 中详细说明 someObject.groups 为空数组。这样,如果您要执行 .map 就不会出错。
    • 使用选择器检索组列表,如果someObject.groups 为空,则返回一个空数组。

    您可以在small test app 中看到我如何做到这一点的示例。具体看一下:

    • /src/index.js 用于初始调度
    • /src/redux/modules/characters.js 供 thunk 使用
    • /src/redux/selectors/characters.js 用于CharacterDetails 组件中使用的漫画、系列等的人口

    【讨论】:

      【解决方案3】:

      一种方法是使用redux-thunk 检查数据是否存在于 redux 存储中,如果不存在,则发送服务器请求以加载缺失的信息。

      您的 GroupPage 组件将类似于

      class GroupPage extends Component {
        componentWillMount() {
          const groupId = this.props.params.groupId
          this.props.loadGroupPage(groupId);
        }
        ...
      }
      

      在你的行动中......

      const loadGroupPage = (groupId) => (dispatch, getState) => {
        // check if data is in redux store
        // assuming your state.groups is object with ids as property
        const {
          groups: {
            [groupId]: groupPageData = false
          }
        } = getState();
      
        if (!groupPageData) {
          //fetch data from the server
          dispatch(...)
        }
      }
      

      【讨论】:

      • 感谢您的回答。你能解释一下吗?请建设const { groups: { [groupId]: groupPageData = false } } = getState();
      • 这是解构赋值的 ES6 特性 (developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…)。所以如果没有找到state.groups[groupId],它会为groupPageData分配一个默认值false
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-15
      • 1970-01-01
      • 2021-07-17
      • 1970-01-01
      • 1970-01-01
      • 2010-09-19
      相关资源
      最近更新 更多