5

I'm trying to add protected routes in App.js for authenticated users but the react element is getting rendered multiple times. Below is my App.js code

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      currentUser: null,
      isAuthenticated: false,
      isLoading: false
    }
  }
  async loadCurrentUser() {
    this.setState({
      isLoading: true
    });
    await getCurrentUser()
      .then(response => {
        this.setState({
          currentUser: response,
          isAuthenticated: true,
          isLoading: false
        });
      }).catch(error => {
        this.setState({
          isLoading: false
        });
      });
  }
  async componentDidMount() { await this.loadCurrentUser(); } render() {
    return (
      <BrowserRouter>
        <React.Suspense fallback={loading}>
          <Switch>
            <Route exact path="/login" component={Login} />
            <Route exact path="/register" component={Register} />
            <ProtectedRoute path="/" name="Home" authenticated={this.state.isAuthenticated}
              component={TheLayout} handleLogout={this.handleLogout}></ProtectedRoute>
          </Switch>
        </React.Suspense>
      </BrowserRouter>
    );

  }
}   
5
  • 2
    Well based on your code it will render 3 times. Once on initial mount, then when you set the isLoading to true, then again when the response comes back. Is it more than that? Also don't mix async/await and .then/.catch syntaxes, can lead to code not behaving the way you think Commented Apr 9, 2021 at 4:03
  • 1
    What do you mean by rendered multiple time? The app will rerender on initial load and every state change. Yours will reload at least 3 times. Commented Apr 9, 2021 at 4:04
  • Thank you Jayce and Sean for your reply. I’m new to React. When I refresh the page after authentication, it is getting redirected to the login page. It is not maintaining the state. Commented Apr 9, 2021 at 4:12
  • 2
    @VimalSaifudin that's because component's state only exists as long as it's mounted. Refreshing the page reloads your entire app. If you want state to exist between page refreshing, you'll have to save your authentication information into local storage and then in your component check if there's authentication info in the local storage - if so, use that as your default state in the constructor, if not then run that API call Commented Apr 9, 2021 at 4:33
  • Hi Jayce, I have saved it in local storage and validating it in componentDidMount method. Should I do this check in the constructor ? Possibly that was the mistake I would have made Commented Apr 9, 2021 at 4:38

2 Answers 2

10

In React, a component re-render occurs when one of two conditions is met: When the props of the component change(i.e, when the parent component passes new props), or when the state is updated. In your case, when your component mounts for the first time, your loadCurrentUser is called, which first sets state(isLoading = true), causing a rerender, and then sets state again, causing another re-render for a total of three renders including the initial render. So if your logs are showing the same number of renders, that is expected behaviour, but if it is re-rendering more than 3 times, check your parent component to see if it is changing the props being passed to this component(I doubt that's the case here, since App component is traditionally the topmost component with no other parent components.

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

Comments

0

Just so you know, if you have strict mode enabled in your react app, it will always render twice on the first render. Strict mode is enabled by default if you created the app using create-react-app, like so:

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
 <React.StrictMode>
 <App />
 </React.StrictMode>
);

To disable strict mode, you can comment out <React.StrictMode>.

You can see this page for more info

1 Comment

Be aware that React recommend keeping strict mode: react.dev/reference/react/StrictMode

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.