React中按下Enter键后如何清空输入框?(共享状态实现)
解决方案
核心思路
用单个对象状态管理所有输入框的值,键为输入框的唯一id,值为输入框内容。这样既无需为每个输入框单独声明状态,又能通过React状态实现受控组件,避免直接操作DOM。
修改后的代码
App.tsx
import React, { useState } from 'react' import './App.css' import { Header } from './components/Header' import { Balance } from './components/Balance' function App() { const [alexBalance, setAlexBalance] = useState(0) const [yuliaBalance, setYuliaBalance] = useState(0) // 用对象存储所有输入框的值,键为输入框id const [inputValues, setInputValues] = useState<Record<string, string>>({}) const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => { const { id, value } = e.target // 更新对应输入框的值,保留其他输入框的状态 setInputValues(prev => ({ ...prev, [id]: value })) } const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => { if (e.key === 'Enter') { const inputId = e.currentTarget.id calcResult(inputId, inputValues[inputId] || '') // 清空当前输入框的状态(若需清空所有,改为setInputValues({})) setInputValues(prev => ({ ...prev, [inputId]: '' })) } } const calcResult = (id: string, val: string) => { const numVal = Number(val) switch (id) { case 'deposit-Alexander': setAlexBalance(prev => prev + numVal) break case 'withdraw-Alexander': setAlexBalance(prev => prev - numVal) break case 'deposit-Yulia': setYuliaBalance(prev => prev + numVal) break case 'withdraw-Yulia': setYuliaBalance(prev => prev - numVal) break } } return ( <div className='App'> <Header /> <div className='wrapper flex flex-wrap justify-around'> <Balance user='Alexander' onChange={handleChange} onKeyDown={handleKeyDown} balance={alexBalance} inputValues={inputValues} /> <Balance user='Yulia' onChange={handleChange} onKeyDown={handleKeyDown} balance={yuliaBalance} inputValues={inputValues} /> </div> </div> ) } export default App
Balance.tsx
import { Input } from './Input' import React from 'react' type BalanceProps = { user: string balance: number onKeyDown: React.KeyboardEventHandler<HTMLInputElement> onChange: React.ChangeEventHandler<HTMLInputElement> inputValues: Record<string, string> } export const Balance = (props: BalanceProps) => { return ( <div className='balance mb-8 mt-8 border-2 shadow rounded py-8 px-8 w-4/6 max-w-3xl'> <div className='balance__header flex flex-col'> <span className=''> {props.user}'s current balance: {props.balance} </span> <span>Enter a value</span> <Input id={`deposit-${props.user}`} name={`add-${props.user}`} placeholder='+ income' onKeyDown={props.onKeyDown} onChange={props.onChange} value={props.inputValues[`deposit-${props.user}`] || ''} /> <Input id={`withdraw-${props.user}`} name={`sub-${props.user}`} placeholder='- expense' onKeyDown={props.onKeyDown} onChange={props.onChange} value={props.inputValues[`withdraw-${props.user}`] || ''} /> </div> </div> ) }
Input.tsx
import { ChangeEventHandler, KeyboardEventHandler } from 'react' type InputProps = { placeholder: string id: string name: string onKeyDown: KeyboardEventHandler<HTMLInputElement> onChange: ChangeEventHandler<HTMLInputElement> value: string } export const Input = (props: InputProps) => { return ( <div> <input type='text' id={props.id} name={props.name} className='input shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline text-center w-4/6 mt-2 mb-2' onKeyDown={props.onKeyDown} onChange={props.onChange} placeholder={props.placeholder} value={props.value} /> </div> ) }
关键修改说明
- 状态结构调整:将单个字符串状态改为对象,通过输入框
id作为键,实现多输入框状态的集中管理,避免多个useState。 - 受控组件改造:给每个
input绑定value属性,完全由React状态控制输入框内容,符合React数据流向规范。 - 清空逻辑优化:按下Enter后,仅更新当前输入框对应的状态字段为空白(若需要清空所有输入框,将
setInputValues(prev => ({ ...prev, [inputId]: '' }))改为setInputValues({})即可)。 - 安全取值:使用
inputValues[inputId] || ''避免未初始化字段导致的undefined问题。
内容的提问来源于stack exchange,提问作者Ram
相关产品推荐
相关产品推荐

