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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 00:41:14