React is not re rendering after an API call and changing the state

I just got into react and was trying to fetch some data from my api, but changing the state doesnt trigger the re-rendering of the component.I have some code inside the useeffect function in my component that fetch my api and then set the states passed as props. This is the states declared on App.js:

  const [username,setUsername] = useState("");
  const [all,setAll] = useState([]);
  const [today,setToday] = useState([]);

I’m passing them and their set functions as props to APP.js, where i use the useeffect function to fetch data and set the states. This is what the beggining of the component code looks like:

const APP = ({username,all,setAll,today,setToday}) => {  
    useEffect(() => {
        axios.get(`http://localhost:3001/api/${username}`)
        .then(response =>{
            let data = [response.data];
            setAll(data[0]);
            console.log(all);
            const t = all.filter((task) => task.title === "a");
            setToday(t);
            console.log(today);
        });
    }, []);

The problem is, the data gets fetched with no problem, and setAll also works and triggers the re-render, but setToday does nothing (it’s guaranteed that there is a task with a title equal to “a”).When I console log {all} in the fifth line of useeffect it just prints an empty array even though the re-render happended and im showing the tasks of {all} in the page after re-rendering. Is it because when it gets to the antepenultimate line the tasks of {all} wheren’t set yet? If that’s the case how can i wait before I filter the tasks and then set the other state? I know there are some similar questions to this one but none of the answers in those questions helped me.

Answer

        setAll(data[0]);
        const t = all.filter((task) => task.title === "a");

The problem is basically that at the time where you’re declaring const t = all.filter((task) => task.title === "a");, all is still an empty array.

See, when you use setAll, it’s basically telling react: hey, when you finish rendering this, set all to the value data[0]. That does not happen immediately, it happens in the next cycle.

What I’d do if I were you would be something like this:

const APP = ({username,all,setAll,today,setToday}) => {  
useEffect(() => {
    axios.get(`http://localhost:3001/api/${username}`)
    .then(response =>{
        const data = [response.data];
        const responseAll = data[0];
        const t = responseAll.filter((task) => task.title === "a");

        setAll(responseAll);
        setToday(t);
    });
}, []);