React项目中使用Styled Components时输入框光标频繁失焦问题的解决求助
Hey there, I spot the exact problem right away—you've defined your Styled Components (Header, Input, Button) inside the Search functional component!
Here's why that causes the cursor bug: every time your Search component re-renders (which happens every time you type a character and trigger setCity to update the city state), these styled components get re-created from scratch. React sees them as entirely new DOM elements, so it unmounts the old input box and mounts a brand new one. That's why your cursor jumps out after each keystroke—you're effectively typing into a new input every time! This doesn't happen with plain CSS because your DOM elements stay the same, only their styles change.
The Fix: Move Styled Components Outside Your Functional Component
Just relocate all your styled component definitions to the top level of your file, outside the Search function. This way, they're created once when the module loads, not on every render.
Here's your corrected code:
import React, { FC, useState, FormEvent } from 'react'; import { useDispatch } from 'react-redux'; import styled from 'styled-components'; import { setAlert } from '../store/actions/alertActions'; import { getWeather, setLoading } from '../store/actions/weatherActions'; // Move styled components OUTSIDE the Search component const Header = styled.h1` font-size: 40px; font-family: 'sans-serif'; padding-top: 30px; `; const Input = styled.input` font-size: 18px; padding: 10px; margin: 10px; background: #b4e6df; border: none; border-radius: 3px; ::placeholder { color: black; } `; const Button = styled.button` background-color: #10e2f1; font-size: 20px; color: white; margin: 1em; border: 3px; padding: 0.25em 6em; `; interface SearchProps { title: string; } const Search: FC<SearchProps> = ({ title }) => { const dispatch = useDispatch(); const [city, setCity] = useState(''); const changeHandler = (e: FormEvent<HTMLInputElement>) => { setCity(e.currentTarget.value); } const submitHandler = (e: FormEvent<HTMLFormElement>) => { e.preventDefault(); if(city.trim() === '') { return dispatch(setAlert('City is required!')); } dispatch(setLoading()); dispatch(getWeather(city)); setCity(''); } return( <> <Header >{title} <form onSubmit={submitHandler}> <Input type="text" placeholder="Enter city name" value={city} onChange={changeHandler} /> <br/> <Button >Search</Button> </form> </Header> </> ); } export default Search;
That's it—your input cursor should stay put now as you type, just like it did with plain CSS!
内容的提问来源于stack exchange,提问作者React Dev

