Search code examples
node.jsreactjsuse-effectsetstate

How to loop in useEffect and setState


I have categories and every category has subcategories, and i want to setState a dictionary like

{category1.name: [/*list of all subcategories*/], category2.name: [...]}

and i have

useEffect(()=>{
        Axios.get("http://localhost:3001/categories/get").then((p) => { /* return a list of categories */
            setCategories(p.data)
            let actual = {}
            for (let i = 0; i < p.data.length; i++) {
                Axios.get("http://localhost:3001/category/subcategories", { /* return all the subcategories of p.data[i], this is working! */
                params : {category : p.data[i].category}}).then((p) => {
                    actual = {...actual, [p.data[i].category]: p.data}
                    console.log(actual) /* 1 */
                })
            }
            console.log(actual) /* 2 */
        })
    }, [])

I already have the backend working, but when i console.log(actual) /* 2 */ its just a empty dictionary {}; and when i console.log(actual) /* 1 */ its not empty (has just 1 element), and i don't know when can i setState(actual), someone know how to do what i want?


Solution

  • You can just use async/await to works like what you need.

    EDIT (mentioned by @skyboyer):

    When you do a network call all requests will go sequentially and loading will take N×time_to_load_one

    Try this out.

    useEffect(()=>{
            Axios.get("http://localhost:3001/categories/get").then(async (p) => { /* return a list of categories */
                setCategories(p.data)
                let actual = {}
                for (let i = 0; i < p.data.length; i++) {
                    await Axios.get("http://localhost:3001/category/subcategories", { /* return all the subcategories of p.data[i], this is working! */
                    params : {category : p.data[i].category}}).then((p) => {
                        actual = {...actual, [p.data[i].category]: p.data}
                        console.log(actual) /* 1 */
                    })
                }
                console.log(actual) /* 2 */
            })
        }, [])