skip to Main Content

I have a useRef() hook that I’m using in a parent component to keep track of if this is the user’s first time on the landing page. This hook is passed to a child component, where it is used to decide which of two CSS classes to style a div with, after which the hook is updated so we know in the future that it’s not their first time. These are the two components:

function RootComponent() {
  const firstLanding = useRef(true);
  return (
    <div>
      <BrowserRouter>
        <Route exact path='/'>
          <Welcome firstLanding={firstLanding} />
        </Route>
        ... other routes
      </BrowserRouter>
    </div>
  );
}
function Welcome(props) {
  var classUsed;

  if (props.firstLanding.current) {
    classUsed = "firstLandingClass";
    props.firstLanding.current = false;
  }
  else {
    classUsed = "normalClass";
  }
  
  console.log("Class used: " + classUsed);
  
  return (
    <div className={classUsed}>
      Content!
    </div>
  )
}

I was expecting this to work, but the first time visiting the site, it logs "Class used: firstLandingClass" and nothing else, while actually using normalClass (Confirmed by inspecting div in browser). Any ideas on why it’s using the other class without logging a change to classUsed in the console or a better way to accomplish this task?

Any and all contributions are very much appreciated!

2

Answers


  1. Can you try this, hope this will help you.

    function Welcome(props) {
      console.log("props", props)
      const [classUsed, setClassUsed] = useState('');
    
      useEffect(() => {
        if (props.firstLanding?.current ) {
          setClassUsed('firstLandingClass');
          props.firstLanding.current = false;
        }
        else {
          setClassUsed('normalClass');
        }
      },[]);
    
      console.log("Class used: " + classUsed);
      
      return (
        <div className={classUsed}>
          Content!
        </div>
      )
    }
    
    Login or Signup to reply.
  2. use useEffect and set the dependency array empty so that it’ll run at once.

    import React, { useState, useRef, useEffect } from "react";
    
    const MyComponent = ({ isFirstRender }) => {
      const [inputValue, setInputValue] = useState("");
    
      useEffect(() => {
        if (isFirstRender.current) {
          isFirstRender.current = false;
        }
      }, []);
    
      return (
        <div
          className={isFirstRender.current ? "First render" : "Not first render"}
        >
          <input
            type="text"
            value={inputValue}
            onChange={(e) => setInputValue(e.target.value)}
          />
          <h1>First Render: {isFirstRender.current ? "Yes" : "No"}</h1>
        </div>
      );
    };
    
    export default function App() {
      const isFirstRender = useRef(true);
    
      return <MyComponent isFirstRender={isFirstRender} />;
    }
    

    If you want to play around with the code

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search