2
votes

I have refactored a form with React hooks and useState, but I can't fire the function handleChange which is provided to onChange of input tags. Here is the code: The useState method

const [data, setData] = useState({
    newDate: '',
    startTime: '',
    endTime: '',
});

const { newDate, startTime, endTime } = data;

The handleInputChange method

const handleInputChange = (e) => {
    console.log('Inside handleChange');
    setData({ ...data, [e.target.name]: e.target.value });
};

The inputs in the form

<input type="text" name="newDate" value={newDate} className="datepicker"
placeholder="Meeting Date" onChange={handleInputChange} />

<input style={{ width: '40%', marginRight: '10%' }} type="text" required
name="startTime" value={startTime} placeholder="00:00" onChange={handleInputChange}
className="timepicker" placeholder="Start Time" />

The onSubmit method and everything apart from this is working, but the input onChange method isn't firing. What exactly am i doing wrong here and how do I fix it?

3
Can you make a reproducible example in a snippet or something? Right off I'm not seeing the issueBrian Thompson
for my checking its work goodOmer
Ok, so I finally figured out that it was because of the input type text and className datepicker and timepicker of materialize css which I was using, I changed it to normal date input and time input and it works just fine.Utkarsh Kumar

3 Answers

1
votes

The code seems ok, you're using controlled components along with computed property names to dynamically update each input value. Perhaps there's a typo somewhere? Also, I would double check that handleInputChange is inside the main function component.

Working example based on your code:

function App() {
  const [data, setData] = React.useState({
    newDate: "",
    startTime: "",
    endTime: ""
  });

  const handleInputChange = e => {
    setData({ ...data, [e.target.name]: e.target.value });
  };
  const { newDate, startTime, endTime } = data;
  return (
    <div>
      <input
        style={styles.input}
        type="date"
        name="newDate"
        value={newDate}
        className="datepicker"
        onChange={handleInputChange}
      />

      <input
        style={styles.input}
        type="time"
        required
        name="startTime"
        value={startTime}
        onChange={handleInputChange}
        className="timepicker"
      />

      <input
        style={styles.input}
        type="time"
        required
        name="endTime"
        value={endTime}
        onChange={handleInputChange}
        className="timepicker"
      />
      {JSON.stringify(data)}
    </div>
  );
}

const styles = {
  input: {
    margin: "20px auto",
    width: "40%",
    display: "block",
  }
};

ReactDOM.render(<App/>, document.getElementById('root'));
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>

Note: I added specific <input> types based on the data you're collecting.

0
votes
<input type="text" name="newDate" value={newDate} className="datepicker"
placeholder="Meeting Date" onChange={(e) => handleInputChange(e)} />

weird, try this.

0
votes

In my case it was global handler attached to window with e.preventDefault() that was preventing onChange.

So if you come here with non-working onChange handler - you might want to check if there's any.