如何等待直到Redux准备必要的数据

时间:2019-04-18 04:11:32

标签: javascript reactjs redux

我正在为我的多语言应用程序和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);

调试时,我看到activeLanguage的生命周期内可用。  我如何在致电render()

之前等待该属性

3 个答案:

答案 0 :(得分:1)

使用诸如Thunk之类的商店增强中间件。您似乎正在发出异步请求,而存储增强器使您可以进行异步调用并从后端检索数据。诸如Thunk之类的中间件将停止默认的动作分派,执行异步请求并调用该分派,以将动作以及更新后的有效负载传递给reducer。在async - await中使用适当的componentDidMount也可以解决此问题,但存储增强器实际上可以为您处理。 这是一个示例:

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

答案 1 :(得分: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 :(得分:0)

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

除此之外,您还应该有一个本地状态变量(例如IsLoading),该变量指示数据尚未准备就绪。等待之后 getAllRestaurants语句,将isLoading设置为falase。

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