Reputation: 156
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
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} />;
}
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>
);
}
Upvotes: 2