0
class SecuredRoute extends Component {
  constructor(props) {
    super(props);
    this.state = {
      reputationNumber: 0,
    }

    this.getReputationNumber = this.getReputationNumber.bind(this);
  }

  componentWillUnmount() {
    this._isMounted = false;
  }

  componentWillMount() {
    this._isMounted = true;
    this.getReputationNumber();
  }

  getReputationNumber() {
    axios.get(`http://localhost:3000/api/userDatas/${getUserDataId()}`)
      .then(response => {
        const reputationNumber = response.data.reputationNumber;
        this._isMounted && this.setState({ reputationNumber });
      }).catch(err => console.log(err));
  }

  render() {
    const { component: Component, path } = this.props;
    const { reputationNumber } = this.state;
    return (
      <Route path={path} render={() => {
        console.log("reputationNumber: ", reputationNumber);
        if (isUserAuthenticated() && reputationNumber >= 500) {
          return <Component />
        }
        else {
          this.props.history.push('/login');
          return <div></div>
        }

      }} />
    );
  }
}


<SecuredRoute exact path='/tag/add' component={AddTag} />

I am just doing a Q&A web app like SO. I am trying to secure my route, /tag/add, users have reputation number and this component checks if the user is authenticated and have a reputation number >= 500 if so it returns the Component else it redirects to login. But the problem is at the first rendering i don't know the reputation number of the user, it comes from the server so between this time the user always redirect to '/login' but i want the user to access the /tag/add component if he is authenticated and have reputation number >= 500.

Any help appreciated.

1 Answers1

0

The way I have always handled the display for data I am anticipating to act on, but have not yet received, it to display a loading indicator until the desired data is returned.

Adding a flag to track whether or not you have received an initial response can be done within the components state:

  constructor(props) {
        super(props);
        this.state = {
            reputationNumber: 0,
            loaded = false, //Add to init state
        }
        
        this.getReputationNumber = this.getReputationNumber.bind(this);
    }
    
  getReputationNumber() {
        axios.get(`http://localhost:3000/api/userDatas/${getUserDataId()}`)
            .then(response => {
                const reputationNumber = response.data.reputationNumber;
                this._isMounted && this.setState({ reputationNumber, loaded: true });
            }).catch(err => console.log(err));
    }

Hope this helps!

Calvin Ellis
  • 185
  • 8