Rolodecks Rolodecks - 4 months ago 11
Javascript Question

AppBar contents are wrong after refresh or hitting back button

I am using ReactJS with Material-UI, which I am both quite new to using.

I have an AppBar component that is used as a main menu/navigation bar. I would like the title of the AppBar component to reflect the page I'm on. So if I press a button that routes the user to /login , I also want to change the title of the AppBar component to "Login". I have accomplished this but there seem to be some side effects so I doubt it's the proper practice.

At the moment, my AppBar component looks like so:

render() {
let MenuOptionsNotLogged = ({}) => (
<div>
<FlatButton
label="Log In"
containerElement={<Link to="/login" />}
secondary
linkButton
onClick={this.switchToLogin}
/>
</div>
);
return (
<div>
<MuiThemeProvider muiTheme={muiTheme}>
<div className="headerDiv">
<AppBar
className="appBar"
showMenuIconButton={this.state.appBarIcon}
title={this.state.appBarTitle}
iconElementRight={<MenuOptionsNotLogged />}
iconElementLeft={<IconButton><BackIcon /></IconButton>}
/>
</div>
</MuiThemeProvider>
</div>
);


In my constructor, I set the default state of the AppBar(the title and icon):

constructor(props, context) {
super(props, context);
this.switchToLogin = this.switchToLogin.bind(this);

this.state = {
appBarTitle: 'Home',
appBarIcon: false
};
}


And then I have a function which changes the title and icon when the user navigates to the Login page:

switchToLogin() {
this.setState({ appBarTitle: 'Log in' });
this.setState({ appBarIcon: true });
}


The problem

This 'works', but it has some problems if the user refreshes or hits the back button on their browser.

E.g. user navigates to /login, title changes to "Login", user refreshes browser. Then the user will be on /login but the title will reset to "Home".

Same problem with the back button. User can navigate to login, press back, and the title will stay as "Login" as opposed to "Home"

Answer

I see you have a Link component. My answer assumes you use react-router.

The problem is that your appBarTitle state is not mapped correctly with the current route. Also when user refresh the browser, the state of components resets.

if you are not using reat-router 3.0, you can get access to the current route through this.context.location.pathname. You will need to read about how to use context here.

Then you can write a helper function to map pathname to the text you want to display: '/login' -> 'Login', '/' -> 'Home'.

Then the title of your AppBar can just be the value returned from the helper function. You no longer need to keep tract of it in the state.

Just to add, not relating to your question, Reactjs is a declarative style of programming, meaning that, 'switchToLogin then display login title' is discouraged. Tell the component what to render rather than how to.

Comments