Search code examples
reactjsarraysinputfocus

React keep focus on re-rendering input


I am building an e-commerce web app, and have run into a problem making an array of inputs. Inside DescHTML I am trying to handle onChange event, but on each update the focus on the element is lost, making it very annoying to type. Does anyone have any solution or different aproach to this whole problem? Thanks in advance.

import {useState} from 'react'

export default function UploadForm() {
  const [name, setName] = useState('')
  const [category, setCategory] = useState('')
  const [film, setFilm] = useState('')
  const [price, setPrice] = useState('')
  
  const [descArr, setDescArr] = useState([''])
  function DescHTML() {
    return (
    <div>
      { descArr.map((item, i) => 
        <input type="text" placeholder="TEST" key={i} value={item} onChange={(e) => {
          e.preventDefault()
          const newArr = [...descArr]
          newArr[i] = e.target.value
          setDescArr(newArr)
        } } /> )}
    </div>
    )
  }

  console.log(descArr)
  

  return (
    <div>
        <form method="POST" action="http://localhost:3500/api/upload" encType='multipart/form-data'>
            <input type="file" name="image" />
            <input type="text" value={name} name="name" onChange={(e) => setName(e.target.value)} placeholder="Product name" />
            <input type="text" value={category} name="category" onChange={(e) => setCategory(e.target.value)} placeholder="Category" />
            <input type="text" value={film} name="film" onChange={(e) => setFilm(e.target.value)} placeholder="Film" />
            <input type="text" value={price} name="price" onChange={(e) => setPrice(e.target.value)} placeholder="Price" />

            <DescHTML />

            <hr />
            {/*<input type="submit" value="Submit" />*/}
        </form>

        <button onClick={() => setDescArr([...descArr, ''])}>+</button>
    </div>
  )
}

Solution

  • Move your descArr and button inside DescHTML check below code you can check more info here.

     function DescHTML() {
        const [descArr, setDescArr] = useState([""]);
        return (
          <div>
            {descArr.map((item, i) => (
              <input
                key={i}
                type="text"
                placeholder="TEST"
                value={item}
                onChange={(e) => {
                  e.preventDefault();
                  const newArr = [...descArr];
                  newArr[i] = e.target.value;
                  setDescArr(newArr);
                }}
              />
            ))}
            <br />
            <button onClick={() => setDescArr([...descArr, ""])}>+</button>
          </div>
        );
      }