Search code examples
reactjsfocus

Losing focus after keystroke in the input component, but works fine with inline JSX


enter image description here

Hi, I want to build a Page with multiple inputs. However, the MyInput component will lose its focus after every keystroke while the inline JSX works fine as above.

The MyInput component is basically as same as the inline JSX, I've no idea why it loses the focus.

You could check the source code from the codesandbox


Solution

  • import "./styles.css";
    import { useState } from "react";
    
    
    function MyInput({
      label,
      value,
      onDataChange
    }: {
      label: string;
      value: number;
      onDataChange: (type: string, amount: number) => void;
    }) {
      const [amount, setAmount] = useState(value);
      return (
        <div>
          <div>Component input: </div>
          <label>{label}: </label>
          <input
            type="number"
            value={amount ?? 0}
            onChange={(e) => {
              const i = parseInt(e.currentTarget.value);
              if (Number.isNaN(i)) return;
              setAmount(i);
              onDataChange("distance", i);
            }}
          />
        </div>
      );
    }
    
    export default function App() {
      const [log, setLog] = useState({
        id: "",
        distance: 0,
        duration: 0,
        weight: 0
      });
    
      function handleLogDataChange(type: string, amount: number) {
        setLog({ ...log, [type]: amount });
      }
    
    
    
      const [distance, setDistance] = useState(log.distance);
      return (
        <div>
          <div>The distance is {log.distance}</div>
          <div>
            <div>Inline input: </div>
            <span>Distance: </span>
            <input
              type="number"
              value={distance ?? 0}
              onChange={(e) => {
                const i = parseInt(e.currentTarget.value);
                if (Number.isNaN(i)) return;
                setDistance(i);
                handleLogDataChange("distance", i);
              }}
            />
          </div>
          <MyInput
            label="Distance"
            value={log.distance}
            onDataChange={handleLogDataChange}
          />
        </div>
      );
    }
    

    just removed MyInput outside of the app. Do not declare a component inside a component