React中使用useState时输入框失焦问题排查求助
React输入框输入时立即失焦的解决办法
问题根源
你的代码里VariantUI组件定义在Footer组件内部,每次Footer因状态更新(比如输入框修改sizeInput、增删颜色/尺寸)重新渲染时,VariantUI都会被重新定义成全新组件。React会卸载旧的VariantUI再挂载新的,这直接导致输入框失去焦点。
另外你更新数组状态时直接修改原数组(比如let temp = sizeArray; temp.push(input);),违反了React状态不可变的原则,也可能引发额外渲染问题。
解决步骤
- 将内部组件移到外部:把
VariantUI和Test组件移到Footer组件外,避免每次渲染都重建组件。需要用到的状态和方法通过props传递。 - 用不可变方式更新数组状态:更新
colorsArray和sizeArray时,不直接修改原数组,而是创建新数组后再调用setter方法。
修改后的完整代码
import React, { useState } from "react"; // 移到外部,所需状态和方法通过props传入 const VariantUI = ({ sizeInput, setsizeInput, sizeArray, sizeElementRemoveHandler }) => { return ( <> <div> <label>Size</label> <input id="optionName" type="text" placeholder="e.g S, M, L, XL" onChange={(e) => { setsizeInput(e.target.value); }} value={sizeInput} /> </div> <ul> {sizeArray.map((data, index) => { return ( <li key={index}> {data} <i onClick={() => sizeElementRemoveHandler(index)}></i> </li> ); })} </ul> </> ); }; const Test = ({ sizeInput, setsizeInput }) => { return ( <input type="text" onChange={(e) => { setsizeInput(e.target.value); }} value={sizeInput} /> ); }; const Footer = ({ formData }) => { const [colorsArray, setColors] = useState(["Red", "Green", "Blue", "Yellow"]); const [sizeArray, setSizes] = useState(["S", "M", "L", "XL"]); const [sizeInput, setsizeInput] = useState(""); const colorElementRemoveHandler = (indexToRemove) => { const filteredValue = colorsArray.filter((data, index) => { return indexToRemove !== index; }); setColors(filteredValue); }; const sizeElementRemoveHandler = (indexToRemove) => { const filteredValue = sizeArray.filter((data, index) => { return indexToRemove !== index; }); setSizes(filteredValue); }; const addColorHandler = (e) => { let input = e.target.value.toLowerCase(); if (input.length > 2) { // 创建新数组,不修改原状态 setColors([...colorsArray, input]); } }; const addSizeHandler = (e) => { let input = e.target.value.toUpperCase(); if (input.length > 0) { // 创建新数组,不修改原状态 setSizes([...sizeArray, input]); } }; return ( <VariantUI formData={formData} sizeInput={sizeInput} setsizeInput={setsizeInput} sizeArray={sizeArray} sizeElementRemoveHandler={sizeElementRemoveHandler} /> ); }; export default Footer;
额外说明
- 你之前用数组index作为key,虽然暂时可用,但如果数组有增删操作,index作为key可能导致React渲染异常,建议如果每个尺寸/颜色有唯一标识(比如id),改用唯一标识当key。
- 状态更新必须遵循不可变原则,直接修改原数组会让React无法正确检测状态变化,引发各种意外问题。
内容的提问来源于stack exchange,提问作者Techguy
相关产品推荐
相关产品推荐

