1

A lot of my components change how they behave based on if the user is logged in or not.

The user is logged in when the local storage has a valid jwt token.

I can add an 'isLoggedIn' boolean to the states of all components that care about this and initialise it but this introduces a lot of redundancy.

Is there a way to have a global prop or state which all components can easily access to take care of this? Perhaps even in the future beyond 'isLoggedIn' I would have other information about the user such as username and things?

5
  • I assume you have the token in window.jwt? If so, just read directly from there. You don't need to have that in your state. Commented Sep 8, 2017 at 12:54
  • You have Redux tagged here. You should be able to use that. Do you have any Redux code we can help you with? Commented Sep 8, 2017 at 13:12
  • @Chris I tried using localStorage.GetItem('jwt') in the render function but I get an error about localstorage being undefined so I assumed that wasn't an option.. Commented Sep 8, 2017 at 13:18
  • @MaxBaldwin I just have the basic React+Redux template from Visual Studio running, I store the jwt token in localStorage, I'm really trying to just understand what the correct way of doing what I've asked using React+Redux. There looks to be a lot of ways of doing it incorrectly, I thought maybe there's a way to have a global store in Redux to accomplish this or something? Commented Sep 8, 2017 at 13:20
  • You're gonna need this (github.com/reactjs/react-redux). And then have a look at the code examples here (redux.js.org/docs/basics/UsageWithReact.html) Commented Sep 8, 2017 at 13:30

2 Answers 2

1

I have quite similar requirements in one of my projects.

store.dispatch(tryAuthenticateFromToken());

ReactDOM.render(
  <Provider store={store}>
    <Router history={browserHistory} />
  </Provider>,
  document.getElementById('root')
);

My solution is to dispatch a login event to the store just before Rendering it. You could do something similar.

Then in a reducer parse that event and save the token somewhere in your store. After that you can use it as any other variable from the store and pass it to the Corresponding Components to render differently based on the login status.

Sign up to request clarification or add additional context in comments.

Comments

1

I dont know redux and im trying to force rerender of the app like this,if you can tell me about potential pitfalls of this solution i would be glad to hear it!

class App extends React.Component {

  constructor(props){
    super(props);

    this.updateCurrentUser = this.updateCurrentUser.bind(this)

    this.state = {

      currentUser:new CurrentUser(this.updateCurrentUser)

    }
    this.logUser = this.logUser.bind(this)
  }

  render() {

    return (

      <div>

      <h4>{"User is logged " + (this.state.currentUser.isLoggedIn()?'in':'out')}</h4>
      <button onClick={this.logUser}>Log in</button>
      </div>

    );


  }
  
  logUser(){
  
    this.state.currentUser.logIn();
  
  }

  updateCurrentUser(currentUser){

    this.setState({

      currentUser:currentUser

    })

  }

  getCurrentUser(){

    return this.state.currentUser

  }

}

class CurrentUser {

  constructor(onChange){
    
    this._isLoggedIn = false;
    this.onChange = onChange
    this.logIn = this.logIn.bind(this);
  }

  /**
   * Log user into the web app
   * @param  {string} email
   * @param  {string} password
   * @param  {function} success  callback
   * @param  {function} fail     callback
   * @return {void}
   */
  logIn(){

    //fake request
    setTimeout(()=>{
    
      this.setProperty('_isLoggedIn',true)
    
    },1500)

  }

  isLoggedIn(){

    return this._isLoggedIn === true

  }
  
  setProperty(propertyName,value){

    this[propertyName] = value
    // update func passed from app
    // updates app state
    this.onChange(this)
  }

}

ReactDOM.render(<App />,document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.