How to make sure this code executes only on initial component mount?

Viewed 31

I have the following Home component:

const Home: FunctionComponent<ScreenProps> = () => {
    const { data: article, isLoading } = useGetArticle('home');

    if (!article || isLoading) return <LoadingIndicator />;

    return (
        <Container>
            <Article article={article} />
        </Container>
    );
};

The problem is that sometimes useGetArticle('home'); executes when it shouldn't which is why I tried changing it a bit and putting it into a useEffect() like this:

const Home: FunctionComponent<ScreenProps> = () => {
    const [article, setArticle] = useState(null);
    const [isLoading, setIsLoading] = useState(true);

    useEffect(() => {
        const { data: articleResponse, isLoading: isLoadingResponse } = useGetArticle('home');

        setArticle(articleResponse);
        setIsLoading(isLoadingResponse);
    }, []);

    if (!article || isLoading) return <LoadingIndicator />;

    return (
        <Container>
            <Article article={article} />
        </Container>
    );
};

but I receive an error because I'm using a React hook inside useEffect - Error: Invalid hook call. Hooks can only be called inside of the body of a function component. So how am I able to go around this?

The rest of the code:

export const getArticle = async (articleId: string): Promise<Article | null> => {
    try {
        const { data } = await request.get(`/articles/${articleId}`);
        return data.article;
    } catch (error) {
        Logger.error(error, `Failed to load article: ${articleId}`);
        return null;
    }
};

export const useGetArticle = (articleId: string) => {
    return useQuery(['getArticle', { articleId }], () => getArticle(articleId), { staleTime: 0 });
};
0 Answers
Related