You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React表单输入单个字符后失焦?重渲染致失焦问题解决咨询

解决React表单输入时每次字符输入后失去焦点的问题

嘿,这个问题我之前也踩过坑!你遇到的输入框每输一个字符就失焦的问题,根源在于你把Finder组件定义在了App组件的内部。

每次App组件因为状态更新(比如你输入字符改变newName)触发重渲染的时候,Finder都会被重新定义成一个全新的组件。这就导致原来的输入框DOM元素被卸载,新的输入框DOM挂载上来,自然就失去焦点了。

下面给你两种简单有效的解决方法:

方法一:将内部组件移到外部,作为独立组件

把Finder组件从App内部抽出来,变成一个独立的组件,然后通过props把需要的状态和回调函数传进去。这样Finder就不会每次App重渲染都被重新创建,输入框的DOM会保持稳定。

修改后的代码:

import axios from 'axios'
import { useState, useEffect } from 'react'

// 独立的Finder组件,接收props
const Finder = ({ newName, handleChange }) => {
  return(
    <div>
      <form>
        <div>
          Find country : <input value={newName} onChange={handleChange} />
        </div>
      </form>
    </div>
  )
}

const App = () => {
  const [countries, setCountries] = useState([])
  const [newName, setNewName] = useState('') // 改成小驼峰命名更符合React规范

  useEffect(() => {
    axios.get('https://restcountries.eu/rest/v2/all')
      .then(response => {
        setCountries(response.data)
      })
  }, [])

  const handleChange = (event) => {
    setNewName(event.target.value)
  }

  return(
    <div>
      <p>Meow</p>
      {/* 传递props给Finder */}
      <Finder newName={newName} handleChange={handleChange} />
    </div>
  )
}

export default App

方法二:直接渲染JSX,不封装内部组件

如果Finder组件的逻辑很简单,没必要单独封装的话,直接把它的JSX内容放到App的return里即可,这样也能避免内部组件重复创建的问题:

import axios from 'axios'
import { useState, useEffect } from 'react'

const App = () => {
  const [countries, setCountries] = useState([])
  const [newName, setNewName] = useState('')

  useEffect(() => {
    axios.get('https://restcountries.eu/rest/v2/all')
      .then(response => {
        setCountries(response.data)
      })
  }, [])

  const handleChange = (event) => {
    setNewName(event.target.value)
  }

  return(
    <div>
      <p>Meow</p>
      {/* 直接渲染输入框,无需封装成内部组件 */}
      <div>
        <form>
          <div>
            Find country : <input value={newName} onChange={handleChange} />
          </div>
        </form>
      </div>
    </div>
  )
}

export default App

补充说明

两种方法的核心都是避免在组件内部重复定义子组件,因为每次父组件重渲染时,内部定义的子组件都会被重新创建,导致DOM树重新生成,输入框自然就失去焦点了。另外顺便提一下,变量名setnewName改成setNewName更符合React的小驼峰命名规范哦~

内容的提问来源于stack exchange,提问作者ilulale

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 11:12:41