skip to Main Content

I’m currently working on a project where I’m using the react-keycloak/web library to handle authentication. I want to display different content based on the initialization state of the Keycloak component. Specifically, when the Keycloak component is initialized, I want to show "Original Content," and when it is not initialized yet, I want to display a "Loading" message.

I’ve tried using the setState() function within a useEffect() hook to update the state and trigger a re-render of my App component. However, it doesn’t seem to work as expected, as the component doesn’t re-render or update when the state changes.

Here is the code:

import { useEffect, useState,} from "react";
import { useKeycloak } from "@react-keycloak/web";

function App() {
    const { keycloak, initialized } = useKeycloak();
    const [isLoading, setIsLoading] = useState(true)


    useEffect(() => {
        console.log("useEffect", initialized)
        if (initialized){
            console.log("isLoading is set to false");
            setIsLoading(false)
        }
    }, [initialized])

    return (<>{isLoading ? <>Loading</>:<>Original Content</>}</>);
}

export default App;

And here is my console log messages:

useEffect false
useEffect false
useEffect false
useEffect false
useEffect true
isLoading is set to false

And what I end up with in my page is the "Loading" content. But I expect it to be "Original Content" according to my code and console log.

What am I missing here?

2

Answers


  1. This answer is outdated due to edits in the question.


    Remove the curly braces

    const rootElement = document.getElementById('root');
    const root = ReactDOM.createRoot(rootElement);
    
    root.render(
      <React.StrictMode>
        <App />
      </React.StrictMode>
    );
    
    function useKeycloak() {
      const [initialized, setInitialized] = React.useState(false);
      setTimeout(() => setInitialized(true), 1500);
      return { keycloak: 0, initialized };
    }
    
    function App() {
      const { keycloak, initialized } = useKeycloak();
      const [isLoading, setIsLoading] = React.useState(true);
    
      React.useEffect(() => {
        console.log('useEffect', initialized);
        if (initialized) {
          console.log('isLoading is set to false');
          setIsLoading(false);
        }
      }, [initialized]);
    
      return isLoading ? <p>Loading</p> : <p>Original Content</p>;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js"></script>
    <div id="root"></div>

    I’d double check your IDE is configured for JS / JSX, the linter on stackblitz caught that immediately.

    Starting the return statement with a curly brace { instead of an HTML tag < tells the JSX compiler that’s an object, not a JSX element.

    Login or Signup to reply.
  2. isLoading should be true every time the script mounts and would be rendered first.
    initialized is a promise, so we wait for the response until is available so in this case to be true.
    I mimicked the promise by using a set timer.

    once useKeycloak is initialized, the useEffect hook is triggered again as its dependancy changes, and isLoading is set to false.

    import React, { useState, useEffect } from "react";
    
    function App() {
      const [isLoading, setIsLoading] = useState(true);
      const [isInitilaized, setIsInitilaized] = useState(false);
      setTimeout(() => {
        setIsInitilaized(true);
      }, 2000);
    
      useEffect(() => {
        console.log("useEffect", isInitilaized);
        if (isInitilaized) {
          console.log("isLoading is set to false");
          setIsLoading(false);
        }
      }, [isInitilaized]);
    
      if (isLoading) {
        return <>is loading...</>;
      }
    
      return <>Original Content</>;
    }
    
    export default App;
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search