【问题标题】:How to make to make sequential async calls and pass data to a sibling component properly?如何进行顺序异步调用并将数据正确传递给兄弟组件?
【发布时间】:2018-08-13 21:46:33
【问题描述】:

我正在尝试构建一个hackernews 克隆作为reactjs 的练习。在这里,我尝试仅使用 react 构建它,稍后我将使用 Redux 构建它。 这是我的组件结构。

--main
  |--menubar
  |--articles

这是项目的codepen

我有两个问题。

1.) 这里我通过状态和道具传递数据。我在menubar 组件上调用componentDidMount 方法中的API,并通过main 组件将其传递给articles 组件。但是当它在componentWillReceiveProps 方法中通过props 接收数据时,它不会呈现列表。要渲染它,我必须单击News(它与获取数据无关,它只是打印一个日志)这将调用 API 方法。通过props接收数据并设置数据时,如何渲染this.state.articleList中的数据。

2.) 在 API 调用中,我已定义仅获取前 20 个帖子。但是当我点击news 时,我每次都会得到随机数量的(

这两个问题是因为异步方法吗?如果是这样,我该如何解决?

【问题讨论】:

    标签: javascript reactjs asynchronous fetch async.js


    【解决方案1】:

    其实是因为异步,我用async library编辑了fetchdata()并添加了getItems()

    使用map的好处是它自己会返回一个结果数组,所以我们不需要维护一个数组。

    var async = require("async");
    
    fetchdata() {
    fetch("https://hacker-news.firebaseio.com/v0/topstories.json")
      .then(res => res.json())
      .then(data => {
        this.setState({ storyList: data }, () => {
          this.getItems(this.state.storyList);
        });
      })
      .catch(err => console.log(`Error fetching data : ${err}`));
      }
    
    
    getItems(storyList) {
        async.mapLimit(storyList, 10,
          function(item, callback) {
            console.log(item);
            fetch(`https://hacker-news.firebaseio.com/v0/item/${item}.json`)
              .then(res => res.json())
              .then(data => {
    
                //pass the data here
                callback(null, data);
              });
          },
          function(err, dataArray) {
            if (err) {
              console.error(err.message);
            } else {
    
              //dataArray will contain an array of results from map
              this.props.getData(dataArray);
            }
          }
        );
      }
    

    【讨论】:

    • 非常感谢。它有效并解决了我遇到的第一个问题。但是即使它没有收到任何文章并将数据正确传递给articles 组件,article 组件也不会呈现文章列表。它仅在我触发诸如单击news 链接(完全独立于此)之类的事件后才会呈现。为什么 ?是不是同样的原因(因为异步)?使用这样的东西有什么缺点吗?性能明智?
    【解决方案2】:
    Hi after getting the data inside getItems binding the data to callback getData as follows
    
    getItems(storyList) {
        var story_list = [];
        async.mapLimit(
            storyList,
            10,
            ((item, callback) =>{
                console.log(item);
                fetch(`https://hacker-news.firebaseio.com/v0/item/${item}.json`)
                    .then(res => res.json())
                    .then(data => {
                        story_list.push(data);
                        this.props.getData(story_list);
                    });
            }),
                ((err) =>{
                if (err) {
                    console.error(err.message);
                } else {
                    this.props.getData(story_list);
                }
            })
        );
    }
    

    【讨论】:

    • 这给出了一个错误说Unhandled Rejection (TypeError): Cannot read property 'props' of undefined 所以我在async.mapLimit 方法之后调用this.props.getData(stroy_list)。它解决了这个问题,但它仍然不会在启动时呈现(即使article 组件接收数据)
    • 是的,调用this.props.getData(story_list) 会出现上述错误。无论如何通过在async.mapLimit函数之后调用它解决了这个问题
    • @ThidasaParanavitharana 你是在 getData() 之后调用 callback() 吗?你能更新你的codesandbox.io/s/qk5qzqzolq 以便我检查并告诉你
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-10
    • 2018-01-27
    • 2018-10-24
    • 2020-09-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多