Search code examples
javascriptreactjsreduxuse-effectreddit

useEffect causing it to call the method to get posts way too many times. I only want to get the posts when my query changes


I am trying to call the reddit API. The post titles are showing up, but I want them to rerender when my query changes. I just want to know how to call a method when a piece of my state changes(aka my query). I’m using useEffect from react to do it but that calls it whenever anything changes in the component, causing it to call the method to get posts way to many times. I only want to get the posts when my query changes.

import React, { useEffect, useState } from 'react';
import { useSelector, useDispatch } from 'react-redux';

function Results()
{   
    const query = useSelector(state => state.query);
    const results = useSelector(state => state.results);

    const dispatch = useDispatch();
    let fetchResults = () =>
    {
        let postTitles = [];
        let postSrcs = [];

        fetch('https://www.reddit.com/r/' + query + '.json')
        .then(response => response.json())
        .then(body => {
            for (let i = 0; i < body.data.children.length; ++i) {
                if (body.data.children[i].data.post_hint === 'image')
                {
                    let img_url = body.data.children[i].data.url_overridden_by_dest;
                    postSrcs.push(img_url);
                }
                let title = body.data.children[i].data.title;
                postTitles.push(title);
            }
            dispatch({type: "QUERY_RESULTS", payload: postTitles})
        }).catch((err) => {
            console.log(err)
        });
    }
    useEffect(() => {
        fetchResults();
        console.log("use effect triggered")
    })
    
  

    return (
        <>
        <h1>Query: {query}</h1>
        
        { !results 
        ? <h1>No Results</h1> 
        : results.map(p => <h6> {p} </h6>)
        }

        </>
    )
}

export default Results;

For example in the console log that tells me when use effect is triggered. and when i search for a post the use effect triggered is stacking up.


Solution

  • useEffect has a differents mode. You can check how to use in official document https://reactjs.org/docs/hooks-reference.html#useeffect

    So the main you must know is 3 things

    1. useEffect is the last render in react. So first render a components and read other code when it finish useEffect run.

    2. useEffect may run code only one time adding []. for example

    useEffect ( () => {
     ...code
    }, [])
    

    This code will run only one time.

    1. useEffect may run code watching variables adding variables into []. For example
    useEffect ( () => {
     ...code
    }, [ count, name , ... ])
    

    This code will run first time and later would run if count or name change