【问题标题】:async/await for fetching data with spinnerasync/await 用于使用微调器获取数据
【发布时间】:2019-04-14 04:32:21
【问题描述】:

目标

让微调器运行直到数据加载。

我做了什么

我关注了this article 我也尝试了常规的承诺和then,但没有成功。

会发生什么

console.log 立即显示“boom”,因此无需等待数据获取。没有错误。

EventPage.js

constructor (props) {
        super(props);
        this.state = {
            panelView: true,
            loading: true
        }
    }

    async componentDidMount () {
        try {
            await this.props.fetchEvents();
            this.setState({loading: false});
            console.log("BOOM")
        } catch {

        }

    }
render() {
        const {loading} = this.state;
        const {panelView} = this.state;
        if (loading) {
            return <Loader />
        }
        return (
            (Actual page)
        )
    }

eventActionCreator fetchEvents

export const fetchEvents = () => {
    return async dispatch => {
        try {
            const response = await axios.get('http://localhost:3090/events');
            dispatch(setEvent(response.data));
            return response.data;
        } catch (e) {
            return e;
        }
    }
}

控制台只是显示代码正在等待 fetch 执行,它没有。

【问题讨论】:

  • 请添加一个带有来自 Stackoverflow 的 JS sn-p 功能的实时示例。
  • 当您说“没有成功”时——实际发生了什么?控制台中是否有错误? “BOOM”会写吗?
  • @bluejack 我添加了详细信息
  • 您的代码中似乎没有错误..您可以添加更多详细信息或工作演示吗?
  • @ma_dev_15 是的...看看下面的答案以及代码沙箱上的现场演示...他在他的 setState 中将 loading 设置为 false ...然后有条件渲染 Loading如果是真的……

标签: reactjs redux async-await es6-promise


【解决方案1】:

试试这个方法

state = {
    products: [],
    loading: true,
  }

  async componentDidMount() {
    // try catch just to make sure we had no errors
    try {
      const res = await fetch('http://api');
      // wait for json to be ready
      const data = await res.json();
      this.setState({
        loading: false,
        data,
      });
      // console.log(product.data.attributes)
    } catch (e) {
      console.log(e);
    }
  }



render() {
    const { data, loading } = this.state;
    return (
      <Container>
        <Contents>
          {loading ? 'loading..' : <Products data={data} />}
        </Contents>
      </Container>
    );
  }

【讨论】:

    【解决方案2】:

    我发现了这个问题。问题是我从动作创建者返回数据,而不是基于承诺的动作。

    所以,而不是

    const response = await axios.get('http://localhost:3090/events');
                dispatch(setEvent(response.data));
                return response.data;
    

    应该是的

    return  axios.get('http://localhost:3090/events')
                .then((response) => {
                    dispatch(setEvent(response.data));
                });
    

    Issue that helped me resolve it

    【讨论】:

      【解决方案3】:

      似乎你把它倒退了......你正在将你的状态初始化为true,然后在cdm中将它设置为false......然后你正在检查加载是否为true,如果是这样渲染加载器......当然,它是不是真的,你把它设置为假...

      改成这样:

      constructor (props) {
              super(props);
              this.state = {
                  panelView: true,
                  loading: false <- here
              }
          }
      
          async componentDidMount () {
          this.setState({loading: true}); <- here
      
              try {
                  await this.props.fetchEvents();
                  this.setState({loading: false}); <- and here...
                  console.log("BOOM")
              } catch {
      
              }
      
          }
      render() {
              const {loading} = this.state;
              const {panelView} = this.state;
              if (loading) {
                  return <Loader />
              }
              return (
                  (Actual page)
              )
          }
      

      这是一个现场演示:https://codesandbox.io/s/r0w381qw3p

      【讨论】:

      • 所以这里有问题`this.setState({loading: true}); 1
      • 如果您需要在组件挂载中加载为 true,请将默认状态设置为 true,而不是在 componentDidMount 中执行,因为它会重新渲染组件
      猜你喜欢
      • 2018-10-17
      • 1970-01-01
      • 2017-10-04
      • 2020-09-09
      • 2020-12-11
      • 1970-01-01
      • 2020-02-02
      • 2020-12-02
      • 1970-01-01
      相关资源
      最近更新 更多