Javascript 在React应用程序中映射阵列以实现性能优化的最佳做法

Javascript 在React应用程序中映射阵列以实现性能优化的最佳做法,javascript,reactjs,Javascript,Reactjs,我有一个简单的字典应用程序,可以返回搜索结果。使用字典的内存数据库,在搜索字段的每个onChange上查询搜索,因此结果非常快 对我来说,优化结果的呈现是很重要的,这样,随着用户类型和查询在每个按键笔划上发生,50个左右的过滤搜索结果会保持流动 以下是我到目前为止所做的:(这很有效,但这是最好/最快的方法吗?) 数据库的每个(同步)查询都会返回一个对象数组,然后我会将其映射为以下内容: queryDB(query) { const results = queryLokiJsDB(query)

我有一个简单的字典应用程序,可以返回搜索结果。使用字典的内存数据库,在搜索字段的每个
onChange
上查询搜索,因此结果非常快

对我来说,优化结果的呈现是很重要的,这样,随着用户类型和查询在每个按键笔划上发生,50个左右的过滤搜索结果会保持流动

以下是我到目前为止所做的:(这很有效,但这是最好/最快的方法吗?)

数据库的每个(同步)查询都会返回一个对象数组,然后我会将其映射为以下内容:

queryDB(query) {
  const results = queryLokiJsDB(query);
  const resultsMapped = results.map((mpd) =>
        <dl key={mpd["$loki"]} onClick={() => this.clickFunction(mpd.p, mpd.f)}>
          <dt>{mpd.p} - {mpd.f}</dt> <dd>{mpd.e} <em>{mpd.c}</em></dd>
        </dl>);
  this.setState({ results: ( 
    <div>
      {resultsMapped}
    </div>
  )});
} 
queryDB(查询){
const results=queryLokiJsDB(查询);
const resultsMapped=results.map((mpd)=>
this.clickFunction(mpd.p,mpd.f)}>
{mpd.p}-{mpd.f}{mpd.e}{mpd.c}
);
this.setState({results:(
{resultsMapped}
)});
} 
然后,一旦我像那样映射了结果,我将映射的组件添加到状态中,然后屏幕就会用新的结果进行渲染

render() {
  return (
    <div>
      <SearchBarStuff />
      <div className="results-container">
          {this.state.results}
      </div>
    </div>
  );
}
render(){
返回(
{this.state.results}
);
}
当我刚刚学习反应时,我就这样做了,我明白人们认为把组件存储在状态中是很不好的做法。 我想知道性能优化方面的最佳实践是什么(以及代码清洁度)我应该将结果数组存储在状态中,然后进行渲染,然后将它们映射到渲染函数中的组件中吗?这会导致性能下降吗?

表示“渲染方法中的一个函数将在每次渲染时创建,这对性能有轻微影响。”


为什么将组件存储在状态中会如此糟糕?这仅仅是为了代码清晰吗?让国家保持小规模?我感谢你的帮助和耐心

我不太确定,但我想的问题与@larz在评论中解释的相同。另外,正如你提到的,州会更清楚。如果我是你,我该怎么办

首先,仅使用结果设置您的状态:

queryDB(query) {
    const results = queryLokiJsDB(query);
    this.setState({ results });
}
然后,映射结果,但不是立即创建JSX,而是使用单独的组件。传递它的
mpd
(元素)和
onClick
函数及其引用

render() {
    return (
        <div>
            <SearchBarStuff />
            <div className="results-container">
                {this.state.results.map( mpd => (
                     <Item key={mpd["$loki"]} mpd={mpd} onClick={this.clickFunction} />
                ) )}
            </div>
        </div>
    );
}

这样,您就不会在
onClick
处理程序中使用箭头函数,因此,由于我们使用了引用,因此不会在每次渲染中重新创建此函数。

如果我猜测,我认为将组件存储在状态中是一种不好的做法,因为React必须将以前的状态与新状态进行比较,以确定是否需要重新渲染,如果它必须在如此大的组件数组而不是对象数组中爬行,那么您正在使它做更多的工作。将对象数组存储在状态中,然后在组件中处理它们的映射和呈现,这无疑是最佳做法。@larz但是React文档说它以一种肤浅的方式比较状态,这意味着对于对象,它只会在引用更改时进行检查。在OP示例中,每次调用
setState({results})
时,React都会立即看到
results
已更改,因为新组件实例将是不同的对象引用。因此,我想说,在这种情况下,性能不会受到影响。嗯。。。对我来说,这实际上似乎让事情慢了一点。可能我的问题是我需要将每个项的参数传递给click函数,因此它必须如下所示:
onClick={()=>this.clickFunction(mpd.foo,mpd.bar)}
。因此,我仍然需要在onClick处理程序中使用arrow函数。(因为
onClick={this.clickFunction(mpd.foo,mpd.bar)}
将在渲染时执行:-(有什么想法吗?你是如何决定这种方式会减慢速度的?不要误解我,我只是想了解这个问题。你的意思是说写这么多代码来减缓速度?如果你愿意,没有单独的组件,你可以使用箭头函数,就像你在这里描述的那样。但是,通过这种方式,该函数将在每次渲染中重新创建。我不知道这对性能有多大影响。有些人说得多,有些人说得少。不,我的意思是在chrome developer工具的“性能”选项卡中查看、编写脚本和渲染时间。但今天我尝试了更多的重构,你建议的方法现在比我以前的设置运行得快多了。(当我第一次尝试时,你的方式似乎慢了20-30%,但我可能是做错了别的事情。)感谢您的帮助。我认为您的方法在代码清洁度和扩展性方面更好,即使它只快了一点点。欢迎您。是的,在React world中分离组件是一种建议的方法。即使在我的示例中
render
方法也有点拥挤:)
.map
可以用单独的方法转到。很高兴您解决了这个问题。
render() {
    return (
        <div>
            <SearchBarStuff />
            <div className="results-container">
                {this.state.results.map( mpd => (
                     <Item key={mpd["$loki"]} mpd={mpd} onClick={this.clickFunction} />
                ) )}
            </div>
        </div>
    );
}