yush
yush

Reputation: 426

ReactJS: Input onChange not Updating State

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

Answers (1)

Drew Reese
Drew Reese

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.

Issue

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.

Solution

<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"
    />
  );
}

Edit reactjs-input-onchange-not-updating-state

Solution 2

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"
    />
  );
}

Edit reactjs-input-onchange-not-updating-state #2

Upvotes: 2

Related Questions