无法实现React表服务器数据加载

时间:2019-09-21 08:33:25

标签: javascript reactjs fetch react-table

我正在测试React-table服务器端数据,以呈现从Web api获取的大量数据,而不会导致浏览器崩溃。使用基本的反应表设置,浏览器将无法处理如此多的记录(500000)并崩溃(它陷入了请求的待处理状态)。

所以我找到了可能对我有帮助的服务器端数据。 我遵循了文档中的说明,但是打字稿抱怨更新状态时要使用的数据。

这是我到目前为止所拥有的:

从Web api获取数据的方法:

private fetchSales() {
  fetch(`http://localhost:50335/api/RK`)
    .then(response => response.json())
    .then(data =>
      this.setState({
        sales: data // here I get 500000 items 
      })
    )
}

此fetchSales在componentDidMount()中被调用。

然后我在render()中有ReactTable组件:

render() {
  const {
    sales,
    pages
  } = this.state;
  return ( 
    <div className = "App" >
    <ReactTable 
      data = {sales}
      manual 
      pages = {pages}
      defaultPageSize = {10}
      onFetchData = {this._fetchData}
      columns = {
      [{
          Header: "Region",
          accessor: "Region"
        },
        {
          Header: "Country",
          accessor: "Country"
        }]
      }
    />
    </div>
  );
}

在ReactTable中,有一个名为_fetchData的函数的调用,该函数如下所示:

private _fetchData(state: any) {
  requestData(
    state.sales,
    state.pageSize,
    state.page
  ).
  then(res => {
    this.setState({
      sales: res.rows, // here typescript complain: "res is of type 'unknown'"
      pages: res.pages // here typescript complain: "res is of type 'unknown'"
    });
  })
}

在setState内,res对象的类型为“未知”,而打字稿不喜欢它。

requestData是一个位于类之外的函数,可获取销售,pageSize和页面状态:

const requestData = (sales: any, page: number, pageSize: number) => {
  return new Promise((resolve, reject) => {
    const res = {
      rows: sales.slice(pageSize * page, pageSize * page * pageSize),
      pages: Math.ceil(sales.length / pageSize)
    }

    resolve(res);
  })
}

该功能几乎与文档中的功能相同,因为我不需要它们,因此仅删除了过滤和排序。我只需要返回该函数的res对象。

我几乎忘记了它,在构造函数中,我将this附加到_fetchData方法:this._fetchData = this._fetchData.bind(this);

为什么打字稿抱怨我试图用来设置状态的res对象?

最诚挚的问候! 美国

1 个答案:

答案 0 :(得分:0)

编辑

我注意到了一些错误。

private _fetchData(state: any) {
  requestData(
    state.sales, // that should be state.data (state is the state of ReactTable)
    state.pageSize,
    state.page
...

接下来,我注意到您在获取数据后进行了分页。但是,将manualonFetchData一起使用是为了在服务器上处理分页。例如,使用pagepageSize,您可以将这些参数传递给您的API。这就是分页的重点!

文档中的示例:

onFetchData={(state, instance) => { //onFetchData is called on load and also when you click on 'next', when you change page, etc.
    // show the loading overlay
    this.setState({loading: true})
    // fetch your data
    Axios.post('mysite.com/data', {
      //These are all properties provided by ReactTable
      page: state.page,
      pageSize: state.pageSize,
      sorted: state.sorted,
      filtered: state.filtered
    })

由于您要一次获取所有内容(为什么?服务器上的API无法处理分页?这样,您不必等待年龄就可以返回结果),那么建议您让ReactTable完成工作。

也就是说,您只需这样做:

<ReactTable
  columns={columns}
  data={data}
/>

ReactTable将处理分页。现在,您可以对ComponentDidMount中的API使用查询。


请您改为尝试将所有逻辑放在onFetchData中。我可能是错的,但在我看来您似乎误解了文档中的说明。 OnFetchDataComponentDidMount处被调用,并不是在告诉您必须将函数放在这里。

private _fetchData(state, instance) {

  const { page, pageSize } = state

  fetch(`http://localhost:50335/api/RK`)
    .then(response => response.json())
    .then(data =>
         let sales = data
         this.setState({
           sales: sales.slice(pageSize * page, pageSize * page * pageSize),
           pages: Math.ceil(sales.length / pageSize)
         });
    )
}

从我收集到的Typescript来看,Typescript没有足够的信息来推断Promise返回的类型。

因此,您必须显式注释Promises泛型类型参数:

return new Promise<{ sales: object; pages: number; }>((resolve, reject) => { ... }