Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/475.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript setState管理大量记录时执行时间长_Javascript_Reactjs - Fatal编程技术网

Javascript setState管理大量记录时执行时间长

Javascript setState管理大量记录时执行时间长,javascript,reactjs,Javascript,Reactjs,我正在尝试解决react应用程序中发生的问题。在其中一个视图(组件)中,我有一个管理工具,可以对大数据进行操作。基本上,当视图加载时,我有componentDidMount,它触发ajax获取,下载由大约50000条记录填充的数组。每个数组行是一个具有8-10个键值对的对象 import React, { Component } from "react"; import { List } from "react-virtualized"; import Select from "react-se

我正在尝试解决react应用程序中发生的问题。在其中一个视图(组件)中,我有一个管理工具,可以对大数据进行操作。基本上,当视图加载时,我有
componentDidMount
,它触发ajax获取,下载由大约50000条记录填充的数组。每个数组行是一个具有8-10个键值对的对象

import React, { Component } from "react";
import { List } from "react-virtualized";
import Select from "react-select";

class Market extends Component {
  state = {
    sports: [], // ~ 100 items
    settlements: [], // ~ 50k items
    selected: {
      sport: null,
      settlement: null
    }
  };

  componentDidMount() {
    this.getSports();
    this.getSettlements();
  }

  getSports = async () => {
    let response = await Ajax.get(API.sports);

    if (response === undefined) {
      return false;
    }

    this.setState({ sports: response.data });
  };

  getSettlements = async () => {
    let response = await Ajax.get(API.settlements);

    if (response === undefined) {
      return false;
    }

    this.setState({ settlements: response.data });
  };

  save = (key, option) => {
    let selected = { ...this.state.selected };
    selected[key] = option;
    this.setState({ selected });
  };

  virtualizedMenu = props => {
    const rows = props.children;
    const rowRenderer = ({ key, index, isScrolling, isVisible, style }) => (
      <div key={key} style={style}>
        {rows[index]}
      </div>
    );

    return (
      <List
        style={{ width: "100%" }}
        width={300}
        height={300}
        rowHeight={30}
        rowCount={rows.length || 1}
        rowRenderer={rowRenderer}
      />
    );
  };

  render() {
    const MenuList = this.virtualizedMenu;

    return (
      <div>
        <Select
          value={this.state.selected.sport}
          options={this.state.sports.map(option => {
            return {
              value: option.id,
              label: option.name
            };
          })}
          onChange={option => this.save("sport", option)}
        />
        <Select
          components={{ MenuList }}
          value={this.state.selected.settlement}
          options={this.state.settlements.map(option => {
            return {
              value: option.id,
              label: option.name
            };
          })}
          onChange={option => this.save("settlement", option)}
        />
      </div>
    );
  }
}
import React,{Component}来自“React”;
从“react virtualized”导入{List};
从“反应选择”导入选择;
类市场扩展组件{
状态={
运动:[],//~100项
结算:[],//~5万项
选定:{
运动:空,
结算:空
}
};
componentDidMount(){
这个。getSports();
这个.getResolutions();
}
getSports=async()=>{
let response=wait Ajax.get(API.sports);
如果(响应===未定义){
返回false;
}
this.setState({sports:response.data});
};
getResolutions=async()=>{
let response=wait Ajax.get(API.response);
如果(响应===未定义){
返回false;
}
this.setState({response:response.data});
};
保存=(键,选项)=>{
让selected={…this.state.selected};
所选[键]=选项;
this.setState({selected});
};
虚拟化菜单=道具=>{
const rows=props.children;
常量行渲染器=({key,index,iscrolling,isVisible,style})=>(
{行[索引]}
);
返回(
);
};
render(){
const MenuList=this.virtualizedMenu;
返回(
{
返回{
值:option.id,
标签:option.name
};
})}
onChange={option=>this.save(“sport”,option)}
/>
{
返回{
值:option.id,
标签:option.name
};
})}
onChange={option=>this.save(“结算”,option)}
/>
);
}
}
我遇到的问题是,在下载大数据并将其保存到view state之后,即使我想使用包含约100条记录的select更新值,也需要几秒钟的时间。例如,假设
smallData
是一个包含100个项的数组,
{id:n,name:'xyz'}
selectedFromSmallData
只是数据数组中的一个项,使用html select进行选择

在加载大数据之前进行选择需要几毫秒,但在加载数据并保存到状态之后,突然需要2-4秒


什么可能有助于解决这个问题(不幸的是,我无法对这些数据进行分页,我无法访问这些数据)

数组的大小不应该是个问题,因为只有引用存储在state对象中,react不会对state执行任何深度相等。 可能您的渲染或组件更新会在这个大数组上迭代,从而导致问题。 如果没有帮助,请尝试评测应用程序。

.map()
在每个渲染上创建一个新数组。要避免这种情况,您有三种选择:

  • 存储
    state.sports
    state.Resolutions
    已为
    Select
  • 每次更改
    状态时。运动
    状态。结算
    也会更改
    状态。运动选项
    状态。结算选项
  • 使用
    componentdiddupdate
    更新
    状态。*选项
  • 第三种选择可能更容易实现。但它将触发额外的重新招标:

      componentDidUpdate(prevProps, prevState) {
        if (prevState.sports !== this.state.sports) {
          this.setState(oldState => ({sportsOptions: oldState.sports.map(...)}));
        }
        ...
      }
    
    每次渲染都会重新创建
    onChange
    处理程序,并可能触发不必要的
    Select
    重新渲染。创建两个单独的方法以避免:

    saveSports = option => this.save("sport", option)
    ...
    render() {
      ...
      <Select onChange={this.saveSports}/>
      ...
    }
    

    如果这不利于考虑使用默认的代码>选择< /代码>,并使用<代码> PueReabor < /Cord>来呈现其选项。或者尝试使用

    PureComponents
    渲染
    选择的部分


    同时选中

    请显示您的
    渲染
    方法。您可能需要将呈现
    state.bigData
    和/或
    state.smallData
    的部分移动到一个单独的PureComponent。您是否尝试在没有更新功能的情况下执行此操作?就凭这个,你说呢?它可能会隔离问题我用源代码更新了我的问题,希望能有所帮助,我尝试避免使用保存方法,我尝试将所选值直接移动到状态,这不会改变任何事情,只要大数据下载,每次保存都需要几秒钟。谢谢你,伙计,事实上,我从你的建议中得到了启发,结果证明,你答案的标题是罪魁祸首。避免
    map(()=>
    几乎完全消除了延迟,我现在在数据下载完成后预先做这些选择,干杯!
        <Select
          components={this.MenuList}
          value={this.state.selected.settlement}
          options={this.state.settlementsOptions}
          onChange={this.saveSettlements}
        />