Reputation: 426
Im running into an issue where the onChange={}
on <input />
doesn't change the value through state.
I have two Components, Component 1 passes the the state of an input value to Component 2 as a prop:
Component 1:
function MainContent() {
const [inputValue, setInputValue] = React.useState("");
const onChangeHandler = (event) => {
setInputValue(event.target.value);
};
return (
<>
<input
id="shtitle"
value={inputValue}
onChange={onChangeHandler}
className="input sh-input"
type="text"
placeholder="Incident Title"
/>
<DuplicateHubDisplay
data={[
inputValue,
momentDate.format("DD/MM/YYYY HH:mm A"),
textareaValue,
]}
/>
</>
);
}
export default MainContent;
Component 2: Gets the prop data from Component 1
const [commsTitle, setCommsTitle] = useState("");
// const [commsTitle, setCommsTitle] = useState(duplicateHubData.data[0]); //Does not work
<input
id="duplicatehub-title"
value={duplicateHubData.data[0]}
className="input"
placeholder="Incident Title"
/>
I don't know how to store duplicateHubData.data[0]
as a state and then use onChange to change the state value.
Doing this does not allow me to change the input value:
const DuplicateHubDisplay = (duplicateHubData) => {
const [commsTitle, setCommsTitle] = useState(duplicateHubData.data[0]);
return (
<input
id="duplicatehub-title"
onChange={(e) => {
setCommsTitle(e.target.value);
}}
value={commsTitle}
className="input"
placeholder="Incident Title"
/>
);
}
export default DuplicateHubDisplay;
Thanks in advance
Upvotes: 2
Views: 5716
Reputation: 202605
If I understand correctly you want DuplicateHubDisplay
's commsTitle
state to update when either (1) the inputValue
of the parent component updates or (2) the input value in DuplicateHubDisplay
updates.
DuplicateHubDisplay
is passed a data
prop where the initial inputValue
state value is ""
, so the initial commsTitle
state is also ""
. DuplicateHubDisplay
doesn't "listen" for updates to props to then update the commsTitle
state.
<DuplicateHubDisplay
data={[
inputValue,
momentDate.format("DD/MM/YYYY HH:mm A"),
textareaValue,
]}
/>
Yes, use an useEffect
hook to react to prop value changes and update the local commsTitle
state.
const DuplicateHubDisplay = ({ data }) => {
const [inputValue] = data; // array destructuring assignment
const [commsTitle, setCommsTitle] = useState(inputValue);
useEffect(() => {
setCommsTitle(inputValue);
}, [inputValue]);
return (
<input
id="duplicatehub-title"
onChange={(e) => setCommsTitle(e.target.value)}
value={commsTitle}
className="input"
placeholder="Incident Title"
/>
);
}
If you don't need to actually do anything with the commsTitle
state you can assign data[0]
as a defaultValue
on the input and use the data[0]
value as a React key so when the value updates from the parent React will remount/reset the input with a new default value.
const DuplicateHubDisplay = ({ data }) => {
const [inputValue] = data; // array destructuring assignment
return (
<input
key={inputValue}
id="duplicatehub-title"
defaultvalue={inputValue}
className="input"
placeholder="Incident Title"
/>
);
}
Upvotes: 2