react is not updating functional component state on input change

12,987

Solution 1

In React, you should avoid doing state-mutations, which means do not explicitly change something belonging to the existing state. In order for React to decide whether or not to re-render to reflect your changes, it needs to register a new-state.

Get in a good habit of creating a clone or deep-copy of the state, and then updating that.

Try something like this instead. In the below, we use the spread operator {...} to clone the state before updating it:

const nullableEntry = {
  ID: "",
  day: "",
  hours: 0.0,
  note: ""
};

const MonthTable = props => {
  const [editing, setEditing] = useState(nullableEntry);

  function handleHoursInput(e) {
    let newEdit = { ...editing };

    newEdit.hours = e.target.value;
    setEditing(newEdit);
  }

  return (
    <input
      type="number"
      value={editing.hours}
      step="0.01"
      onChange={handleHoursInput}
      className="form-control"
      name=""
    />
  );
};

Working sandbox: https://codesandbox.io/s/hopeful-bogdan-lzl76

Solution 2

Do not mutate state, editing.hours = e.target.value mutates original state

change your handleHoursInput function to something like this

function handleHoursInput(e) {
    let hours = e.target.value;
    setEditing({...editing, hours});
}
Share:
12,987
ahmed waleed
Author by

ahmed waleed

Updated on June 21, 2022

Comments

  • ahmed waleed
    ahmed waleed almost 2 years

    When i type input and on change editing.hours doesn't update input value but i see updated value in the console.

    const nullableEntry = {
        ID: '',
        day: '',
        hours: 0.0,
        note: '',
    };
    
    const MonthTable = (props) => {
        const [editing, setEditing] = useState(nullableEntry);
    
        function handleHoursInput(e) {
            editing.hours = e.target.value;
            setEditing(editing);
        }
    
        return (
           <input type="number" value={editing.hours} step="0.01" onChange={handleHoursInput} className="form-control" name="" />
        );
    };
    
    export default MonthTable;