Этот ответ является сводкой статьи Brian Vaughn, наделенной правом , Вам, Вероятно, не нужно Полученное состояние (07 июня 2018).
Происходящее состояние от опор является антишаблоном во всех своих формах. Включая использование более старого componentWillReceiveProps
и более новое getDerivedStateFromProps
.
Вместо того, чтобы получить состояние из опор, рассмотрите следующие решения.
Две рекомендации лучшей практики
Рекомендация 1. Полностью управляемый компонентfunction EmailInput(props) {
return <input onChange={props.onChange} value={props.email} />;
}
Рекомендация 2. Полностью неконтролируемый компонент с ключом // parent class
class EmailInput extends Component {
state = { email: this.props.defaultEmail };
handleChange = event => {
this.setState({ email: event.target.value });
};
render() {
return <input onChange={this.handleChange} value={this.state.email} />;
}
}
// child instance
<EmailInput
defaultEmail={this.props.user.email}
key={this.props.user.id}
/>
Две альтернативы, если, по любой причине, рекомендации не работают на Вашу ситуацию.
Альтернативный 1: Сбросьте неконтролируемый компонент с идентификационной опоройclass EmailInput extends Component {
state = {
email: this.props.defaultEmail,
prevPropsUserID: this.props.userID
};
static getDerivedStateFromProps(props, state) {
// Any time the current user changes,
// Reset any parts of state that are tied to that user.
// In this simple example, that's just the email.
if (props.userID !== state.prevPropsUserID) {
return {
prevPropsUserID: props.userID,
email: props.defaultEmail
};
}
return null;
}
// ...
}
Альтернативные 2: Сбросьте неконтролируемый компонент с методом экземпляра class EmailInput extends Component {
state = {
email: this.props.defaultEmail
};
resetEmailForNewUser(newEmail) {
this.setState({ email: newEmail });
}
// ...
}