Javascript setState管理大量记录时执行时间长
我正在尝试解决react应用程序中发生的问题。在其中一个视图(组件)中,我有一个管理工具,可以对大数据进行操作。基本上,当视图加载时,我有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
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}
/>