Home > front end >  How to clear input field after key('Enter') press on React?
How to clear input field after key('Enter') press on React?

Time:02-01

I am developing a small application where for two different people I display their balance after entering the amount. For example, if Alex's current balance is 100 and I enter a number in the income field, the balance increases. When you enter a number in the expense field, the balance decreases. Same for the second person. I am trying to clear the fields after hitting the enter key.

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)

  const [value, setValue] = useState('')

  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setValue(e.target.value)
  }

  const handleKeyDown = (e: React.KeyboardEvent) => {

    if (e.key === 'Enter') {
      calcResult(e.currentTarget.id, value)
      // document.querySelectorAll('input').forEach(input => (input.value = ''))
    }
  }

  const calcResult = (id: string, val: string) => {
    switch (id) {
      case 'deposit-Alexander':
        setAlexBalance(alexBalance   Number(val))
        break
      case 'withdraw-Alexander':
        setAlexBalance(alexBalance - Number(val))
        break
      case 'deposit-Yulia':
        setYuliaBalance(yuliaBalance   Number(val))
        break
      case 'withdraw-Yulia':
        setYuliaBalance(yuliaBalance - Number(val))
        break
    }
  }

  return (
    <div className='App'>
      <Header />
      <div className='wrapper flex flex-wrap justify-around'>
        <Balance user='Alexander' onChange={handleChange} onKeyDown={handleKeyDown} balance={alexBalance}
        />
        <Balance user='Yulia' onChange={handleChange} onKeyDown={handleKeyDown} balance={yuliaBalance}
        />
      </div>
    </div>
  )
}

export default App

Balance.tsx

import { Input } from './Input'
import React from 'react'

type BalanceProps = {
  user: string
  balance: any
  onKeyDown: React.KeyboardEventHandler
  onChange: React.ChangeEventHandler<HTMLInputElement>
  
}

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}
        />
        <Input
          id={`withdraw-${props.user}`}
          name={`sub-${props.user}`}
          placeholder='- expense'
          onKeyDown={props.onKeyDown}
          onChange={props.onChange}
        />
      </div>
    </div>
  )
}

Input.tsx

import { ChangeEventHandler, KeyboardEventHandler } from 'react'

type InputProps = {
  placeholder: string
  id: string
  name: string
  onKeyDown: KeyboardEventHandler<HTMLInputElement>
  onChange: ChangeEventHandler
}

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}
      />
    </div>
  )
}

I tried this...,

  const handleKeyDown = (e: React.KeyboardEvent) => {

    if (e.key === 'Enter') {
      calcResult(e.currentTarget.id, value)
      document.querySelectorAll('input').forEach(input => (input.value = ''))
    }
  }

it works for me, but, as i know, it's not the best practice. I would like to get a solution using the state. I would not like to use a separate state for each input. Thanks a lot

CodePudding user response:

you do it right just setState to empty when enter clicks , so instead of commented code in e.key==='Enter' block set your desired state to empty e.g.

setAlexBalance(0)
setYuliaBalance(0)
setValue('')
  • Related