我有一个带有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表单相似的解决方法是什么?
答案 0 :(得分:12)
setState
本身并不慢,只有当您的渲染器非常昂贵才开始导致问题。
需要考虑的一些事项是:
render
方法中呈现的子组件不会被不必要地重新呈现。 why-did-you-update可以指出那些不必要的重新渲染。切换到PureComponent
,无状态组件或使用shouldComponentUpdate可以提供帮助。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
。