Редактировать: посмотрите минимальный пример в репозитории git: https://github.com/maximilianschmitt/blind-lifecycle
У меня есть компонент RequireUser
, который пытается убедиться, что пользователь вошел в систему, и в противном случае не будет отображать своих дочерних элементов. Его родительский компонент, App
, должен знать, требуется ли пользователь, и при необходимости отображать форму входа.
Проблема в том, что компонент App
монтируется ПОСЛЕ компонента RequireUser
в дереве следующим образом:
App
RequireUser
SomeOtherComponent
В componentDidMount
RequireUser
я запускаю действие requireLogin
, которое устанавливает для переменной loginRequired
UserStore
значение true
.
Это не обновляет родительский компонент (App
), поскольку он еще не смонтирован и поэтому не может регистрировать изменения в хранилище.
class RequireUser extends React.Component {
constructor() {
super();
this.state = alt.stores.UserStore.getState();
}
componentDidMount() {
this.unlisten = alt.stores.UserStore.listen(this.setState.bind(this));
if (!this.state.requireUser) {
UserActions.requireUser();
// using setTimeout will work:
// setTimeout(() => UserActions.requireUser());
}
}
componentWillUnmount() {
this.unlisten();
}
render() {
if (this.state.requireUser) {
return <div>I have required your user</div>;
}
return <div>I will require your user</div>;
}
}
class App extends React.Component {
constructor() {
super();
this.state = alt.stores.UserStore.getState();
}
componentDidMount() {
this.unlisten = alt.stores.UserStore.listen(this.setState.bind(this));
}
componentWillUnmount() {
this.unlisten();
}
render() {
return (
<div>
<div>User required? {this.state.requireUser + ''}</div>
<RequireUser />
</div>
);
}
}
Выход:
Требуется пользователь? ЛОЖЬ
мне нужен ваш пользователь
Если я использую setTimeout
в RequireUser
, App
получает изменения состояния и визуализирует, но только после мерцания:
Требуется пользователь? истинный
мне нужен ваш пользователь
У меня такое ощущение, что то, что я делаю, является анти-шаблоном, и я был бы признателен за предложения более элегантного решения, чем мерцание с помощью setTimeout. Спасибо!