skip to Main Content

I am currently working on implementing a collapsible sidebar in my React application that relies on a value stored in the local storage. The desired behavior is that if the value is true, the sidebar should have the className of "inline," and if the value is false, the className of "hidden" should be applied.

The implementation of the logic seems to be working as expected, and I am getting the desired result. However, I am encountering the following warning in the browser:

Warning: Prop `className` did not match. Server: "hidden" Client: "inline"

My assumption is that the code itself is functioning correctly. However, when comparing the state between the server and the client, it appears that the server-rendered content takes precedence and always shows the className as "hidden" instead of what should actually be applied.

Here is the relevant code snippet:


  const checkExpanded = () => {
    if (typeof window !== "undefined") {
      const sidebarState = localStorage.getItem("sidebarState");
      if (sidebarState) {
        return JSON.parse(sidebarState);
      }
      return true;
    }
  };

  const [expanded, setExpanded] = useState(checkExpanded());

  const toggleExpanded = () => {
    setExpanded(!expanded);
  };

  // fetch sidebar state from local storage
  useEffect(() => {
    const sidebarState = localStorage.getItem("sidebarState");
    if (sidebarState) {
      setExpanded(JSON.parse(sidebarState));
    }
  }, []);

  // save sidebar state to local storage
  useEffect(() => {
    localStorage.setItem("sidebarState", JSON.stringify(expanded));
  }, [expanded]);


  <span className={expanded ? "inline" : "hidden"}>{item.text}</span>

I would greatly appreciate any insights or suggestions on how to address this warning and ensure that the client-rendered className matches the expected value. Thank you in advance for your help!

Here are the attempted solutions I have already tried:

I verified that the value from the local storage is being read correctly. I ensured that the value retrieval from localStorage.getItem("sidebarState") is functioning as expected.

I investigated whether the value of the sidebar state is being changed anywhere else during runtime. After thorough examination, I concluded that the issue does not lie in the code where the value is modified.

Despite these efforts, the warning persists. It suggests that the mismatch between the server-rendered and client-rendered className props is not caused by a direct issue with the value or its modification.

2

Answers


  1. The problem being that window is not defined on the server side. Therefore expand is null on the server side and true on the client side.
    And so :

    <span className={expanded ? "inline" : "hidden"}>{item.text}</span>
    

    Worth hidden on the server side and inline on the client side

    Login or Signup to reply.
  2. What you can do is import the component dynamically and disable ssr. It would resolve the errors caused by using any browser APIs like window

    import dynamic from 'next/dynamic'
     
    const DynamicComponent = dynamic(() => import('../components'), {
      ssr: false,
    })
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search