【问题标题】:How to wait until redux prepares necessary data如何等到 redux 准备好必要的数据
【发布时间】:2019-04-18 04:11:32
【问题描述】:

我正在为我的多语言应用程序和 MySQL 使用 react-localize-redux 来获取数据。我的一项操作需要语言环境数据将其作为参数传递给后端,以便后端以正确的数据进行响应。但是当区域设置可用时,操作被调用并且应用程序崩溃,我该如何解决这个问题? 这是代码:

import React, { Component } from 'react'
import RestaurantCard from './RestaurantCard';
import {Row} from 'react-bootstrap';
import { connect } from 'react-redux';
import {getAllRestaurants} from "../actions/restaurantActions";
import { withLocalize } from 'react-localize-redux';

class RestaurantCardColumns extends Component {

  constructor(props){
    super(props);
  }

  componentDidMount(){
    this.props.getAllRestaurants(this.props.activeLanguage);
  }

  render() {
    if(this.props.loading || this.props.restaurants === null){
      return <p>Loading...</p>
    } else {
      return (
        <Row>
            <RestaurantCard data = {this.props.restaurants[0]}/>
            <RestaurantCard data = {this.props.restaurants[1]}/>
            <RestaurantCard data = {this.props.restaurants[2]}/>
            <RestaurantCard data = {this.props.restaurants[3]}/>
        </Row>)
    }
  }
}
const mapStateToProps = (state) =>{
  return {
      auth: state.auth,
      errors: state.errors,
      restaurants: state.restaurData.restaurants,
      loading: state.restaurData.loading
  }
}

export default connect(mapStateToProps, {getAllRestaurants})(withLocalize(RestaurantCardColumns));

我的问题出在这一行:

this.props.getAllRestaurants(this.props.activeLanguage);

当我调试时,我可以看到activeLanguagerender() 生命周期中可用。 在调用 getAllRestaurants

之前,我该如何等待该属性

【问题讨论】:

  • mapStateToProps 期间映射它(可以接受props 参数),并且只有在连接器以正确的语言看到数据时才将loading 设置为false。减速器中的 Thunk 可以处理该部分。

标签: javascript reactjs redux


【解决方案1】:

在获取数据之前检查this.props.activeLanguage 的可用性。一旦activeLanguage 可用,就触发获取数据。最后确保提取只发生一次(如果需要)

class RestaurantCardColumns extends Component {

  constructor(props){
    super(props);
    this.didFetch = false; // store outside of state to not trigger rendering
  }

  componentDidMount(){
    this.fetchAllRestaurants();
  }

  componentDidUpdate(prevProps) {
    if (prevProps.activeLanguage !== this.props.activeLanguage) {
      this.fetchAllRestaurants();
    }
  }

  fetchAllRestaurants() {
    if (!!this.props.activeLanguage && !this.didFetch) {
      this.props.getAllRestaurants(this.props.activeLanguage);
      this.didFetch = true;
    }
  }

请注意,这种方法完全依赖于组件的存在,即如果组件不在虚拟 DOM 中,则不会发生 API 调用。您应该考虑使用 redux 的中间件触发调用,例如这里的其他人建议的 redux-thunkredux-saga

【讨论】:

    【解决方案2】:

    使用存储增强器中间件,例如 Thunk。您似乎正在发出异步请求,并且存储增强器使您能够进行异步调用并从后端检索数据。像Thunk 这样的中间件停止默认动作调度,执行异步请求并调用调度以将动作与更新的有效负载一起传递给reducer。在componentDidMount 中使用正确的async - await 也可以处理此问题,但存储增强器实际上会为您处理此问题。 这是一个例子:

    async componentDidMount() {
        await this.props.getAllRestaurants(this.props.activeLanguage);
    }
    

    【讨论】:

    • 次要细节:componentWillMount 是一个已弃用的生命周期。在渲染发生之前可以多次调用它,并且可能不应该使用它。如果您更新 react 组件的本地状态,则会发生重新渲染,这将是一个更稳定的解决方案。 For reference
    • 我确实使用thunk,没有运气
    • @NodirNasirov 在componentDidMount 中使用async - await
    • 这样吗? await this.props.activeLanguage; this.props.getAllRestaurants(this.props.activeLanguage.code);
    • 查看我的答案以获取示例
    【解决方案3】:

    ComponentDidMount 应该是一个异步函数,你应该等待 getAllRestaurants 来完成。

    除此之外,您还应该有一个本地状态变量(例如 IsLoading),它指示数据尚未准备好。在'等待 getAllRestaurants 的声明,您将 isLoading 设置为 falase。

    如果 getAllRestaurants 失败,Render 将检查此本地状态以显示微调器或数据本身,或错误消息(除了检查 isLoading 之外,您还应该检查 redux 存储,您不仅会存储数据, 但也是一个变量,指示 getAllRestaurants 是成功还是失败)。

    【讨论】:

    • 在得到this.props.activeLanguage 参数之前,我无法等待getAllRestaurants,我的问题是如何等待this.props.activeLanguage 以便将其传递给getAllRestaurants
    • 我看到有人在帮助你。如果您发现自己陷入困境,请在此处发表另一条评论,我会尽力提供帮助。
    猜你喜欢
    • 2018-12-03
    • 2011-08-10
    • 1970-01-01
    • 2020-08-07
    • 1970-01-01
    • 2023-01-31
    • 1970-01-01
    • 1970-01-01
    • 2021-04-26
    相关资源
    最近更新 更多