将数据获取组件包装在HOC中以在加载时显示微调器

时间:2017-05-05 14:12:05

标签: javascript reactjs

我有一堆不同的反应组件通过api获取数据,它们每个都有相应的loadData动作和isLoading reducer。我正在尝试编写一个HOC,它将显示加载微调器代替组件,直到加载数据并显示组件。

现在isLoading是真的 - >旋转器渲染 - > isLoading变为false - >子组件呈现 - >孩子的componentDidMount()已执行 - >这再次调用loadData动作,将isLoading设置为false等等。如何防止这种情况并仅调用loadData一次?或者可能有更优雅的解决方案?

class DataList extends Component {
  componentDidMount() {
    this.props.loadData(); //action that pulls data via api
  }

  render() {
    return <p>{this.props.data}</p>;
  }
}

const withSpinner = (comp) => (props) => {
  if (props.isLoading) {
    return <p>Loading...</p>
  } else {
    return <comp {...props} />
  }
}

export default connect()(withSpinner(DataList));

// action that fetches data and updates state
const loadData = () => {
  setIsLoading(true);
  data = await fetchData();
  setIsLoading(false);
}

2 个答案:

答案 0 :(得分:1)

嗯,您可以解决此问题的最简单方法之一是在您维护状态的位置添加dataLoaded值,并在加载数据时将其设置为true。然后,只需在调用loadData之前添加一个检查,这将阻止其他加载请求。它看起来像这样:

class DataList extends Component {
  componentDidMount() {
    if (!this.props.dataLoaded) { // call it whatever you want
      this.props.loadData(); //action that pulls data via api
    }
  }

  render() {
    return <p>{this.props.data}</p>;
  }
}

const withSpinner = (comp) => (props) => {
  if (props.isLoading) {
    return <p>Loading...</p>
  } else {
    return <comp {...props} />
  }
}

export default connect()(withSpinner(DataList));

// action that fetches data and updates state
const loadData = () => {
  setIsLoading(true);
  data = await fetchData();
  setIsLoading(false);
  setIsLoaded(true);
}

或者,您也可以将dataLoaded置于loadData函数内,如果您可以访问其中的状态

答案 1 :(得分:1)

这里有很多选择。非常简单的解决方案是仅在数据不存在时才加载数据:

componentDidMount() {
  if (!this.props.data) {
     this.props.loadData();
  }
}

您还可以将新标志引入状态,该状态将指示是否加载数据。 其他解决方案是直接在HOC中加载数据。