Diego
Diego

Reputation: 681

Warning: Expected server HTML to contain a matching <section> in <div>. ---- Next.js / react

It's my firs time using next.js, and i'm having some problems...

So i'm just doing my app normally, and i looked at the dev tools, and there's this problem

enter image description here

Now, my first thought was, ok, i didn't close a html tag and i looked at my Navbar an AuthContext components, and that wasn't the problem, so, i really don't know what is goin on, and i hope you can help me with this.

Let me show you the components

Navbar

import { NavbarHeader } from "./NavbarStyled";
import Part1 from "./Parts/Part1";
import Part2 from "./Parts/Part2";
import Part3 from "./Parts/Part3";

const Navbar = () => {
  if (typeof window !== "undefined") {
    var auth = JSON.parse(localStorage.getItem("Auth"));
  }
  return (
    <>
      {auth ? (
        <NavbarHeader>
          {/* Go home icon - search bar */}
          <Part1 />
          {/* Middle Icons */}
          <Part2 />
          {/* User information */}
          <Part3 />
        </NavbarHeader>
      ) : (
        <div></div>
      )}
    </>
  );
};

export default Navbar;

This is the AuthContext

import { createContext } from "react";

import {
  Actions,
  dataObject,
  LOGIN,
  LOGOUT,
  LOGINLOADING,
  LOGINNOLOADING,
  REGISTERLOADING,
  REGISTERNOLOADING
} from "../GlobalInterfaces/AuthContextInterfaces";
import { useReducer } from "react";
import { useContext } from "react";

interface Istate {
  loginLoading: boolean;
  registerLoading: boolean;
  data?: dataObject | null;
}

const DefaultState = createContext<Istate>({
  loginLoading: false,
  registerLoading: false
});

const DispatchActions = createContext(null);

const localReducer = (state: Istate, action: Actions): Istate => {
  switch (action.type) {
    case LOGINLOADING:
      return {
        ...state,
        loginLoading: true
      };

    case LOGINNOLOADING:
      return {
        ...state,
        loginLoading: false
      };

    case REGISTERLOADING:
      return {
        ...state,
        registerLoading: true
      };

    case REGISTERNOLOADING:
      return {
        ...state,
        registerLoading: false
      };

    case LOGIN:
      localStorage.setItem("Auth", JSON.stringify({ ...action.payload }));
      return {
        ...state,
        loginLoading: false,
        registerLoading: false,
        data: action.payload
      };

    case LOGOUT:
      localStorage.removeItem("Auth");
      return {
        ...state,
        data: null
      };

    default:
      return state;
  }
};

export const AuthContext = ({ children }: { children: React.ReactNode }) => {
  const [state, dispatch] = useReducer(localReducer, {
    registerLoading: false,
    loginLoading: false,
    data: null
  });

  return (
    <DefaultState.Provider value={state}>
      <DispatchActions.Provider value={dispatch}>
        {children}
      </DispatchActions.Provider>
    </DefaultState.Provider>
  );
};

export const AuthData = () => useContext(DefaultState);
export const AuthActions = () => useContext(DispatchActions);

What does that problem mean, and what might be causing it ?

Thanks for your time !

Upvotes: 5

Views: 14147

Answers (1)

Ivan V.
Ivan V.

Reputation: 8081

Your server and browser rendered html output don't match. I believe the culprit is your Navbar component, html produced on the server is just an empty div, while in the browser it will be <NavBarHeader> content.

You need to run the auth logic only in the browser, the way you do it in Next.js is to use useEffect.

  //Navbar
  const [auth,setAuth] = useState()
  useEffect(()=>{

    var auth = JSON.parse(localStorage.getItem("Auth"));
    setAuth(auth)
  },[])

Upvotes: 6

Related Questions