Reputation: 2033
I dont understand why the input loses focus after typing one character when the component is defined inside an other component. I read in other answers to use ref. But it does not work.
Does not work:
import React, { useState, useRef } from "react";
import ReactDOM from "react-dom";
function MyApp() {
const [text1, setText1] = useState("");
const [text2, setText2] = useState("");
const ref1 = useRef(null)
const ref2 = useRef(null)
const TextInput = ({ref, text, onChange }) => {
return <input ref={ref} defaultValue={text} onChange={onChange} />;
};
const onChange1 = e => {
setText1(e.currentTarget.value);
};
const onChange2 = e => {
setText2(e.currentTarget.value);
};
return (
<form className="App">
<TextInput ref={ref1} text={text1} onChange={onChange1} />
<TextInput ref={ref2} text={text2} onChange={onChange2} />
</form>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<MyApp />, rootElement);
When I define the compoent outside everything works fine.
Does work:
import React, { useState, useRef } from "react";
import ReactDOM from "react-dom";
const TextInput = ({ref, text, onChange }) => {
return <input ref={ref} defaultValue={text} onChange={onChange} />;
};
function MyApp() {
const [text1, setText1] = useState("");
const [text2, setText2] = useState("");
const ref1 = useRef(null)
const ref2 = useRef(null)
const onChange1 = e => {
setText1(e.currentTarget.value);
};
const onChange2 = e => {
setText2(e.currentTarget.value);
};
return (
<form className="App">
<TextInput ref={ref1} text={text1} onChange={onChange1} />
<TextInput ref={ref2} text={text2} onChange={onChange2} />
</form>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<MyApp />, rootElement);
Upvotes: 0
Views: 3420
Reputation: 443
You are recreating TextInput
whenever the input value changes and the MyApp
component renders. If you want to include TextInput
component inside of MyApp
component, you can use useCallback
hook to prevent the recreation of TextInput
when the component renders.
import React, { useState, useRef, useCallback } from "react";
import ReactDOM from "react-dom";
function MyApp() {
const [text1, setText1] = useState("");
const [text2, setText2] = useState("");
const ref1 = useRef(null);
const ref2 = useRef(null);
const TextInput = useCallback(({ ref, text, onChange }) => {
return <input ref={ref} defaultValue={text} onChange={onChange} />;
}, []);
const onChange1 = e => {
setText1(e.currentTarget.value);
};
const onChange2 = e => {
setText2(e.currentTarget.value);
};
return (
<form className="App">
<TextInput ref={ref1} text={text1} onChange={onChange1} />
<TextInput ref={ref2} text={text2} onChange={onChange2} />
</form>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<MyApp />, rootElement);
Upvotes: 3