Edit: Check out the git repository for a minmal example: https://github.com/maximilianschmitt/blind-lifecycle
I have a component RequireUser
that tries to ensure that the user is logged in and will otherwise not render its children. Its parent component, App
, should know if a user is required and render a login form if needed.
The problem is, that the App
component mounts AFTER the RequireUser
component in a tree like this:
App
RequireUser
SomeOtherComponent
In RequireUser
's componentDidMount
I am triggering an action requireLogin
that sets the UserStore
's loginRequired
variable to true
.
This does not update the parent component (App
) because it has not yet been mounted and can therefor not register changes to the store.
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>
);
}
}
Output:
User required? false
I have required your user
If I use setTimeout
in RequireUser
, App
receives the state changes and renders, but only after a flicker:
User required? true
I have required your user
I have the feeling what I am doing is an anti-pattern and I would be grateful for suggestions of a more elegant solution than flickering with setTimeout. Thanks!