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
Destructuring is basically syntatic sugar Some Eslint configurations prefer it (which I'm guessing is your case).
It's basically declaring the values and making them equal to the bit of syntax you don't want to repeat, for Ex, given react props:
this.props.house, this.props.dog, this.props.car
destructured --->
const { house, dog, car } = this.props;
So now you can just use house, or dog or whatever you want. It's commonly used with states and props in react, here is more doc about it, hope it helps. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With