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

React中styled-components包裹的input输入框按键后失焦如何解决

问题根因

输入框每次输入单个字符就失焦,核心原因是你将styled-components生成的FormControl组件定义写在了CourseInput函数组件的内部。
当输入内容触发state更新时,CourseInput会重新执行渲染,每一次渲染都会创建一个全新的FormControl组件。React在diff时会判定新旧FormControl不是同一个组件,直接卸载旧组件、挂载新组件,旧组件内部的input会被直接销毁,新挂载的input默认没有焦点,就出现了按一次键就失焦的现象。

除此之外你的代码还有4处会导致功能/样式异常的问题:

  • 两处样式插值里把props拼写为porps,会导致invalid状态的样式读取失败
  • input的background样式规则末尾缺少分号,会导致后续样式解析失效
  • input没有绑定value属性,不是标准的受控组件,极端场景会出现状态和输入值不同步的问题
  • 你给input加的固定key无法解决失焦问题:父组件FormControl已经被判定为新节点,内部所有子元素都会被重新挂载,给子元素加key不生效。
修复步骤
  1. 将FormControl的定义移动到CourseInput函数组件的外部,保证组件只在文件初始化时创建一次,重渲染时不会被识别为新组件
  2. 修正porps的拼写错误,补全缺失的样式分号
  3. 给input绑定value属性对应enteredValue状态,移除input上多余的固定key
修复后完整代码
import React, { useState } from 'react';
import styled from 'styled-components';

import Button from '../../UI/Button/Button';
import './CourseInput.css';

// styled组件移到函数组件外部定义,避免重渲染时重新创建
const FormControl = styled.div`
  margin: 0.5rem 0;

  & label {
    font-weight: bold;
    display: block;
    margin-bottom: 0.5rem;
    color: ${props => props.invalid ? 'red' : 'black'};
  } 
  & input {
    display: block;
    width: 100%;
    border: 1px solid ${props => (props.invalid ? 'red' : '#ccc')};
    background: ${props => props.invalid ? '#ffd7d7' : 'transparent'};
    font: inherit;
    line-height: 1.5rem;
    padding: 0 0.25rem;
  } 
  & input:focus {
    outline: none;
    background: #fad0ec;
    border-color: #8b005d;
  }
`;

const CourseInput = props => {
  const [enteredValue, setEnteredValue] = useState('');
  const [isValid, setIsValid] = useState(true);

  const goalInputChangeHandler = event => {
    if (event.target.value.length > 0) {
      setIsValid(true);
    }
    setEnteredValue(event.target.value);
  };

  const formSubmitHandler = event => {
    event.preventDefault();
    if (enteredValue.trim().length === 0) {
      setIsValid(false);
      return;
    }
    props.onAddGoal(enteredValue);
  };

  return (
    <form onSubmit={formSubmitHandler}>    
      <FormControl invalid={!isValid}>
        <label>Course Goal</label>
        <input type='text' value={enteredValue} onChange={goalInputChangeHandler} />
      </FormControl>
      <Button type="submit">Add Goal</Button>
    </form>
  );
};

export default CourseInput;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 02:45:34