为什么 React 中 onChange 事件会触发多次?与 state 类型和严格模式有何关系?

为什么 React 中 onChange 事件会触发多次?与 state 类型和严格模式有何关系?

React onChange 事件触发多次:深入探究其原因

在 React 应用开发中,onChange 事件触发多次的情况时有发生,这常常令人困惑。本文将详细分析此问题,并探讨其与 useState 类型和严格模式的关系。

以下示例代码演示了这个问题:输入一个字符,控制台会打印两次日志。然而,将 useState({}) 替换为 useState(3)(将状态类型从对象改为原始类型),日志只会打印一次。这说明状态类型会影响 onChange 事件的触发次数。

import React, { useState } from "react";  export default function Child() {   const [state, setState] = useState({}); // 更改为 useState(3) 则只触发一次    const onChange = (e) => { // 注意添加事件参数e     console.log("onChange triggered", state, e.target.value); // 添加输出e.target.value     setState({...state, value: e.target.value}); //更新state   };    return (     <div>       <input type="text" onChange={onChange} />     </div>   ); }

这种现象与 React 的严格模式 (StrictMode) 密切相关。在开发环境中启用严格模式,React 会故意进行两次渲染,以帮助开发者尽早发现潜在问题,例如不必要的副作用。这两次渲染分别用于检测副作用和实际的 dom 更新。

当状态为对象类型时,由于对象是引用类型,在 setState 后,对象的引用地址发生了变化。React 在严格模式下,会检测到这种变化,从而触发两次渲染,导致 onChange 事件被调用两次。而原始类型(如数字)则不会出现这种情况,因为其值本身被直接更新,不会产生新的引用地址。

React 文档中强调,组件应尽可能保持为纯函数,即相同的输入(props、state 和 context)应该始终产生相同的输出。严格模式通过两次渲染来帮助开发者识别违反此规则的情况。

因此,在开发过程中遇到 onChange 事件触发多次的问题时,务必检查:

  1. 是否启用了严格模式: 在开发环境中,严格模式会触发两次渲染。
  2. 状态类型: 使用原始类型状态可以避免因引用类型变化导致的重复渲染。
  3. 事件处理函数: 确保事件处理函数内部逻辑正确,避免不必要的重复状态更新。 (在上面的修改代码中,我们添加了事件参数e,并使用e.target.value来获取输入值,更清晰地展示了状态更新。)

理解 React 严格模式及其对不同数据类型的影响,对于编写高效、可预测的 React 应用至关重要。 在生产环境中,通常会禁用严格模式,从而避免性能问题。

© 版权声明
THE END
喜欢就支持一下吧
点赞6 分享