Home > Blockchain >  Input loses focus after typing character React
Input loses focus after typing character React

Time:12-14

I've been trying to debug this for hours and looked at every single other Stack Overflow question that has the same style of issue, but they all just say to use keys and that's still not working for me. I've made a simpler example of my code that replicates the error.

    import React from 'react'
import { useState } from 'react'
const FormTest = () => {

    const [name, setName] = useState('')
    const TestExperience = (props) => {
        return (<div>
           <h1>Test Experience {props.num}</h1>
          <input 
           type="text" 
           name="name" 
           placeholder="Name"
            />
        </div>)
    }
    const processFormData = (event) => {
        event.preventDefault();
        console.log(event.target);
    }
    const [nums, setNums] = useState([1, 2, 3]);
    const arr = nums.map((num, index) => <TestExperience num={num} key={index}/>);

    return (
        <div>
            <form onSubmit={(event) => {
                processFormData(event);
            }}>
            {arr}
            
            <button onClick={() => {
                setNums([...nums, nums.length   1]);
            }}>Add one!</button>
            </form>        
        </div>
    )
}

export default FormTest

I've tried moving TestExperience to it's own, separate function. I'm trying to basically have inputs that one can create more of, and this issue of losing focus came from the fact that every time an input was added, all of the existing formData disappeared due to a re-render. The goal would be to just use the onSubmit function to parse the data, but since it disappears after adding the input I figured I needed to store it. I've been going down rabbit hole after rabbit hole trying to fix what seems like such a simple problem and just keep running into issues with every implementation I try.

The overall goal is that I have a submit button and an add input button, and I tried to ditch the whole value={stateVariable} and onChange={setStateVariable} thing and just make the input button a "submit" button so that I can run the processFormData and do different things based on which submit button it was, but I have no clue how to check which button the submit came from when there's two different buttons, so an answer to that could be super helpful as well because then I can avoid this whole state mess.

CodePudding user response:

You need to move the TestExperience out of FormTest.

import React from "react";
import { useState } from "react";

const TestExperience = (props) => {
  const [name, setName] = useState("");

  return (
    <div>
      <h1>Test Experience {props.num}</h1>
      <input
        type="text"
        name="name"
        placeholder="Name"
        onChange={(event) => {
          event.preventDefault();
          setName(event.target.value);
        }}
        value={name}
      />
    </div>
  );
};

const FormTest = () => {
  const processFormData = (event) => {
    event.preventDefault();
    console.log(event.target);
  };
  const [nums, setNums] = useState([1, 2, 3]);
  const arr = nums.map((num, index) => (
    <TestExperience num={num} key={index} />
  ));

  return (
    <div>
      <form
        onSubmit={(event) => {
          processFormData(event);
        }}
      >
        {arr}
        //another way I tried to do it below //
        {nums.map((num, index) => (
          <TestExperience num={num} key={index} />
        ))}
        <button
          onClick={() => {
            setNums([...nums, nums.length   1]);
          }}
        >
          Add one!
        </button>
      </form>
    </div>
  );
};

export default FormTest;

Code sandbox => https://codesandbox.io/s/trusting-elbakyan-mxrez?file=/src/App.js

  • Related