Search code examples
reactjstypescriptreact-hooksreact-typescripttsx

React with TypeScript - React has detected a change in the order of Hooks called by ComponentName


I am working with a project with users. Right now I am working with the UserProfile

This is the error I am recieving.

React has detected a change in the order of Hooks called by UserProfile

   Previous render            Next render
       ------------------------------------------------------
    1. useState                   useState
    2. useContext                 useContext
    3. useEffect                  useEffect
    4. undefined                  useContext

Let me show some code of the UserProfile component.

export const UserProfile = () => {
    document.title = `${title} - My Profile`;
    const [profile, setProfile] = useState<UserDetails>();

    const {claims} = useContext(AuthContext);

    const getUserEmail = (): string => {
        return claims.filter(x => x.name === "email")[0]?.value.toString();
    }

    useEffect(() => {
        axios.get(`${urlAuth}?userName=${getUserEmail()}`)
            .then((response: AxiosResponse<UserDetails>) => {
                setProfile(response.data);
            })
    }, [getUserEmail]);

    return (
        profile ? 
        <article>
            <h1>This profile belongs to {UserName()}</h1>
            <h2>{profile.name}</h2>
        </article>
        : <div>Loading...</div>
    )
}

I get a warning at the getUserEmail function,

It says

    The 'getUserEmail' function makes the dependencies of useEffect Hook (at line 26) change on every render. 
Move it inside the useEffect callback. 
Alternatively, wrap the definition of 'getUserEmail' in its own useCallback() Hook.

I am not sure on how this should be done. Any ideas on what I could do?

Thanks


Solution

  • The reason why you are getting error about order of hooks is I think because of this:

      profile ? 
            <article>
                <h1>This profile belongs to {UserName()}</h1>
                <h2>{profile.name}</h2>
            </article>
            : <div>Loading...</div>
    

    If UserName is a component you should not call it as function, rather as element <UserName/>. When you call it as function react thinks some of the hooks which you call inside it belong to the parent component - this combined with condition profile ? could give you the error.