Categories
destructuring eslint javascript reactjs

Destructuring state/props in React

I’m learning React and I have Eslint installed in my project. It started giving me errors like

Use callback in setState when referencing the previous state. (react/no-access-state-in-setstate)
Must use destructuring state assignment (react/destructuring-assignment)

I tried to look this up but couldn’t understand properly.

Can someone point me in the right direction with this?

Here is my code that throws the errors:

class LoginForm extends React.Component {
state = {
data: {
email: "",
password: "",
},
loading: false,
errors: {},
};
onChange = e =>
this.setState({
data: { ...this.state.data, [e.target.name]: e.target.value },
});
onSubmit = () => {
const errors = this.validate(this.state.data);
this.setState({ errors });
if (Object.keys(errors).length === 0) {
this.setState({ loading: true });
this.props
.submit(this.state.data)
.catch(err =>
this.setState({
errors: err.response.data.errors,
loading: false,
}),
);
}
};
}

As I understand I would need to destructure this.state and this.props but how?

EDIT:
After following the suggestions below, I ended up with this. All I need to fix right now is the props. Its asking me to use a destructuring props assignment.

onChange = ({ target: { name, value } }) =>
this.setState(prevState => ({
data: { ...prevState.data, [name]: value }
}));
onSubmit = () => {
const { data } = this.state;
const errors = this.validate(data);
this.setState({ errors });
if (Object.keys(errors).length === 0) {
this.setState({ loading: true });
this.props
.submit(data)
.catch(err =>
this.setState({ errors: err.response.data.errors, loading: false })
);
}
};

Thanks in advance and sorry for the newbie question.

What eslint is telling you with the react/destructuring-assignments error is that assignments like:

const data = this.state.data;

can be rewritten into:

const { data } = this.state;

This also works for function arguments, so:

onChange = e => { ... }

can be written as

onChange = ({target: {value, name}}) => { ... }

The next error for react/no-access-state-in-setstate tells you that you are writing:

this.setState({
data: { ...this.state.data, [e.target.name]: e.target.value }
});

when you should be writing:

this.setState(prevState => ({
data: { ...prevState.data, [e.target.name]: e.target.value }
}));

or, if you combine it with the react/destructuring-assignments rule:

onChange = ({target: {name, value}}) =>
this.setState(prevState => ({
data: { ...prevState.data, [name]: value }
}));

You can read more about those two rules here:

react/destructuring-assignment

react/no-access-state-in-setstate