LeeJaeWon
LeeJaeWon

Reputation: 21

React Hook must be called in the exact same order BUT I got an exception

I've already understood "React Hook must be called in the exact same order."

So I think in following case it might be an error

export default function(onClick) {
    if (typeof onClick !== "function") {
        return;
    }
    const element = useRef();
    useEffect(() => {
        if (element.current) {
            element.current.addEventListener("click", onClick);
            element.current.style.cursor = "pointer";
        }
        return () => {
            if (element.current) {
                element.current.removeEventListener("click", onClick);
            }
        };
    }, []);
    return element;
}

But this code works! I don't know why... And I have other one, this is driving me crazy.

Look at this case:

export default function onClick(onClick) {
    if (typeof onClick !== "function") {
        return;
    }
    const element = useRef();
    useEffect(() => {
        if (element.current) {
            element.current.addEventListener("click", onClick);
            element.current.style.cursor = "pointer";
        }
        return () => {
            if (element.current) {
                element.current.removeEventListener("click", onClick);
            }
        };
    }, []);
    return element;
}

I just named function and It give an error to me...

Please let me know why upper case's hook is not an error?


I got it!

It is just ES-lint's bug

cf)https://github.com/facebook/react/issues/19155

Upvotes: 0

Views: 7587

Answers (2)

Gabriel Lupu
Gabriel Lupu

Reputation: 1447

I ran into the same warning. It was because I had a condition similar to yours:

if (typeof onClick !== "function") {
  return;
}

above the hook.

Because of this condition, the hook will not run every time. That's where the warning is coming from. I moved my condition after the hook and now everything is fine.

Upvotes: 0

sgrmhdk
sgrmhdk

Reputation: 236

Just change the order of if block..

Don’t call Hooks inside loops, conditions, or nested functions. Instead, always use Hooks at the top level of your React function. You can follow the documentation here.

export default function(onClick) {
    
    const element = useRef();
    useEffect(() => {
        if (element.current) {
            element.current.addEventListener("click", onClick);
            element.current.style.cursor = "pointer";
        }
        return () => {
            if (element.current) {
                element.current.removeEventListener("click", onClick);
            }
        };
    }, []);
    return element;

if (typeof onClick !== "function") {
        return;
    }

}

Upvotes: 1

Related Questions