olwg199
olwg199

Reputation: 15

React.useState() hook doesn't reflect new value

QUESTION: Why my setContact() function doesn't work?

My hook declaration:

const [contact, setContact] = useState({
fName: "",
lName: "",
email: ""});

My UI element:

<input
      name="email"
      placeholder="Email"
      onChange={catchEmail}
      value={contact.email}
    />

My onChange handler:

function catchEmail(event) {
const { value: email } = event.target;
setContact((prevValue) => {
  prevValue.email += email;
  return prevValue;
});

}

I know how to make it work, but I want to understand what's wrong with this code.

Upvotes: 0

Views: 470

Answers (1)

CertainPerformance
CertainPerformance

Reputation: 370729

Changing the DOM is (sometimes) expensive. React, understanding this, does not re-render components if the new state is exactly the same (===) as the old state.

Here, since you're mutating the existing state and returning it, the new state is the same object as the old state, so React skips re-rendering.

You need to return a new object, so React knows to re-render.

setContact(prevValue => ({
  ...prevValue,
  email
}));

(you don't want to concatenate onto the existing email value, you want to set the new email state value to the new full input value, almost certainly)

You can also avoid this problem by separating out the different stateful values, eg, do:

const [email, setEmail] = useState('');
onChange={e => setEmail(e.target.vaue)}

as is usually recommended with hooks.

Upvotes: 4

Related Questions