在 React 组件中显示并行 Ajax 请求的结果

Show Result from Parallel Ajax request in React Component

我正在尝试用 Reactjs 重写我的旧项目。由于我是初学者,这是我的第一个应用程序,我需要一些帮助来了解什么是 React 方式的最佳方式,以及我如何改进自己和这个演示项目。

这是其中的 working demo

我想在 Ajax 请求完成后立即显示名称,而不是等待 Promise 中的所有请求完成。

ListManager.js

import React, { Component } from 'react'
import List from './List'

export class ListManager extends Component {
  constructor (props, context) {
    super(props, context)
    this.state = {finaldata: []}
  }

  componentWillMount () {
    const id = [1, 2, 3, 4, 5]
    this.APIres(id)
  }

  APIres (ids) {
    Promise.all(ids.map(id => fetch('http://api.tvmaze.com/shows/' + id).then(resp => resp.json().then(data => data.name))
    )).then(data => {
      data.sort()
      this.setState({finaldata: Object.assign(this.state.finaldata, data)})
    })
  }

  render () {
    return (
      < div>
        <h3>{this.props.title}< /h3>
        <List data={this.state.finaldata} />
      < /div >
    )
  }
}

List.js

'use strict'
import React, { Component } from 'react'

const ListItem = ({ text }) => <li>{text}</li>

const List = ({ data }) => {
  const listNodes = data.map((value, index) => <ListItem text={value} key={index}></ListItem>)

  return <ul>{listNodes}</ul>
}
export default List

一些注意事项:id 数组将带有 URL 查询,如 example.com/#/?id=1,2,3,4。我将为此使用 react-router。

有办法

1 带序列 DEMO

所有提取同时开始(出于性能原因),但数据将按 ID 的顺序出现

  APIres (ids) {
    ids.map(id => fetch('http://api.tvmaze.com/shows/' + id).then(resp => resp.json()) )
    .reduce((sequence,promise)=>
    sequence.then(()=>promise)
    .then(({name})=>{
        this.setState({finaldata: [...this.state.finaldata, name]});
    }), Promise.resolve());
  }

2 序列不保证 DEMO

所有提取同时开始(出于性能原因),但数据将按照请求响应的顺序出现,这可能与 ids 顺序不同

  APIres (ids) {
    ids.forEach(id => fetch('http://api.tvmaze.com/shows/' + id).then(resp => resp.json())
     .then(({name})=>{
      this.setState({finaldata: [...this.state.finaldata, name]})
    }))
  }

3 setState 前排序

数据将按请求响应的顺序出现,但排序将通过sort()

实现
  APIres (ids) {
    ids.forEach(id => fetch('http://api.tvmaze.com/shows/' + id).then(resp => resp.json())
     .then(({name})=>{
      this.setState({finaldata: [...this.state.finaldata, name].sort()})
    }))
  }