SnaccOvenFlour
SnaccOvenFlour

Reputation: 156

Problem with an input tag in a function - React JS

So I'm trying to render an input tag conditionally so that is why I'm using a function instead of just putting it all into a return statement. The issue I'm encountering is whenever I type a single word into an input tag it looses focus and I have to click it again to re-gain focus. My code is like this:

function App() {
    function InputTag() {
        if (someCondition) {
            return (
                <input onChange={(e) => setState(e.target.value)} value={State} />
            )
        } else {
            return (
                <input disabled value={State} />
            )
        }
    }
    return (
        <div>
            <InputTag />
        </div>
    )
}

After some de-bugging I've found that this issue occurs when I'm using a function to return an input tag but in my case I have to use a function to return the input tag.

You can experience this issue at : https://codesandbox.io/s/xenodochial-bassi-3gmyk

Upvotes: 3

Views: 215

Answers (1)

ksav
ksav

Reputation: 20830

InputTag is being redefined every time App renders. And App is re-rendering every time the onChange event is fired because its state is being updated.

One solution would be to move InputTag outside of App, passing the state and state setter as component props.

import { useState } from "react";

export default function App() {
  const [State, setState] = useState("");

  return (
    <div className="App">
      <InputTag State={State} setState={setState} />
    </div>
  );
}

function InputTag({ State, setState }) {
  return <input onChange={(e) => setState(e.target.value)} value={State} />;
}

Edit boring-sara-l3yvr


However, It's not so clear why you say you need to use a function to do some conditional rendering.

If you are only making the input disabled based on someCondition, you can easily do that in App's return statement.

import { useState } from "react";

export default function App() {
  const [state, setState] = useState("");
  const [someCondition, setSomeCondition] = useState(true);

  return (
    <div className="App">
      <input
        onChange={(e) => setState(e.target.value)}
        value={state}
        disabled={!someCondition}
      />

      <button onClick={() => setSomeCondition(!someCondition)}>
        someCondition: {someCondition.toString()}
      </button>
    </div>
  );
}

Edit holy-framework-w8n1m

Upvotes: 2

Related Questions