响应输入onChange滞后

时间:2018-06-12 14:09:32

标签: reactjs

我有一个带有onChange事件处理程序的简单控制输入。

每次按键时handleChange触发一切都会正常工作,问题是非常慢

使用输入时,非常明显滞后。是否有一些额外的代码,我必须正确使其像正常输入一样工作?

我必须去抖输入吗?

据我所知,在文档中没有提到这个问题,我也不知道是否有额外的事情需要做,或者我是否正在使用{ {1}}回调错误。

onChange

组件:

handleChange = (event) => {
    this.setState({ itemNumber: event.target.value })
  }


<TextField
      id="Part #"
      label="Part #"
      value={this.state.itemNumber}
      onChange={this.handleChange}
      margin="normal"
    />

我正在观看chrome中的devtools的状态更新,并且在输入的字符和状态更新之间至少有500毫秒的延迟,更快的打字时间更长。为什么setState这么慢?使此表单的行为与普通Web表单相似的解决方法是什么?

7 个答案:

答案 0 :(得分:12)

setState本身并不慢,只有当您的渲染器非常昂贵才开始导致问题。

需要考虑的一些事项是:

  • 您的主要组件似乎非常大,并且在每次击键时都会重新呈现,因此可能会导致性能问题。尝试将其分解为更小的组件。
  • 确保在主组件的render方法中呈现的子组件不会被不必要地重新呈现。 why-did-you-update可以指出那些不必要的重新渲染。切换到PureComponent,无状态组件或使用shouldComponentUpdate可以提供帮助。
  • 虽然你不能避免在这里重新渲染(因为你的表单输入需要使用新的状态值重新渲染),但是通过分成更小的组件,你可以使用shouldComponentUpdate让React知道组件的输出是否是不受当前状态或道具变化的影响,避免不必要的重新渲染。
  • 切换到生产版本以获得更好的性能
  • 切换到uncontrolled components并让DOM自己处理输入组件(这是您描述的“正常Web表单”行为)。当您需要访问表单的值时,您可以使用ref来访问底层DOM节点并直接从中读取值。这样就不需要调用setState,因此需要重新呈现

答案 1 :(得分:2)

这似乎是一个微不足道的响应,但是 — 确保您的控制台已关闭。控制台打开时,受控组件存在明显滞后!

答案 2 :(得分:1)

您可以使用https://reactjs.org/docs/perf.html来分析您的应用。您是否有大量可以重新渲染的组件?可能需要向组件添加一些componentShouldUpdate()方法,以防止无用的重新渲染。

答案 3 :(得分:1)

当一个输入中的更改触发整个组件的重新渲染(除非您有相应的解决方法)时,这对于大型表单是一个特殊的问题,这就是为什么它似乎滞后了。

如果您希望控制您的输入并具有相同的确切行为,那么您始终可以这样做

<input
  className="form-control"
  type="text"
  name="name"
  defaultValue={form.name}
  onBlur={onChangeHandler}
 />

这只会触发模糊事件,并防止每次更改重新渲染。这很有用,因为当您单击任何其他按钮来处理数据时,可以确保您拥有更新的状态。

如果您的逻辑需要与输入数据相关的即时验证/处理,这将无济于事。

注意:请阅读onBlur事件here

答案 4 :(得分:0)

我在开发模式下输入速度很慢也遇到了类似的问题,但是功能组件和挂钩都存在。生产还可以,但是显然打开生产似乎不是一种方法,如果在开发模式下运行太慢,则很有可能存在代码问题。因此,解决方案是将输入状态与其余组件隔离。组件所使用的状态应仅对此组件可用。实际上,这甚至不是解决方案,而是事物的反应方式。

答案 5 :(得分:0)

我最近遇到了同样的问题,我有一个redux商店和一个描述,在描述输入中每次击键都必须更新该商店之后,我尝试在lodash中进行反跳,但并没有工作,所以我创建了一个设置超时功能来像这样简单地更新商店状态,

 setTimeout(() => {
  console.log("setting");
  this.props.addDescription(this.state.description);
}, 200);

我从描述组件自身的状态中获取描述输入字段值,每当重新渲染时,我就使用componentDidMount()从商店中获取最新的更新描述值。

答案 6 :(得分:0)

如果你正在使用一个有太多重新渲染依赖的大型父组件 我建议您在子组件的 useEffect 中处理重新渲染 或者是否强制使用父级中的所有状态更新 在子组件中使用 debounce

相关问题