Search code examples
reactjsreact-routerreact-reduxreact-redux-form

Re renderling AppBar component in React


I have an AppBar Component as shown below

<AppBar title="Shopping List App" showMenuIconButton={true}
                    iconElementRight={checkAuthenticationToken()?<Menu/>:null}
                    iconElementLeft={<IconButton><NavigationClose /></IconButton>}
                />

the iconElementRight should only render the Menu Component after the checkAuthenticationToken() evaluates to true which it does after login. However, it is not and I have to manually refresh the browser for it to show up. I believe it is because nothing is changing for the AppBar component and therefore its render method is not called again. My question Is how Can I refresh the AppBar or all ReactDom on successful login?

ReactDOM.render(
    <Provider store={store}>
        <BrowserRouter>
            <MuiThemeProvider muiTheme={getMuiTheme(muiTheme)}>
                <AppBar title="Shopping List App" showMenuIconButton={true}
                    iconElementRight={checkAuthenticationToken()?<Menu/>:null}
                    iconElementLeft={<IconButton><NavigationClose /></IconButton>}
                />
                <div className="container">
                    <Switch>
                        <Route exact path="/" render={requireLogin}/>
                        <Route path="/login" render={isLoggedIn}/>
                        <Route path="/register" component={RegisterForm}/>
                        <Route path="/shoppinglists" render={requireLogin}/>
                        <Route path="/:id/shoppinglist_items" render={itemsRequireLogin}/>
                        <Route component={NotFound}/>
                    </Switch>
                </div>
            </MuiThemeProvider>
        </BrowserRouter>
    </Provider>
    , document.getElementById('root'));

Solution

  • If your component is't connected to redux store, state changes won't trigger a new render, so you won't have your component updated.

    The way it is right now, it'll only perform this check when the render method get's called...

    One possible solution is wrap your AppBarcomponent into another one that is connected to redux state, so it'll update whenever the part of the state you need is updated in the store

    const mapStateToProps = (state, ownProps) {
      const { isAuthenticated } = state.authentication // Get whatever you need from the reducer that handles authentication state
      return { isAuthenticated } 
    }
    
    class MyAppBar extends Component {
      ...
    
      render(){
        return(<AppBar iconElementRight={this.props.isAuthenticated ? <Menu /> : null} {rest of your props})
      }
    }
    
    export default connect(mapStateToProps)(MyAppBar)
    

    This way, any changes on the store related to the authentication reducer will be tracked by the component and will trigger the render method (Performing the check when it's needed)