Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

useEffect within a custom hook doesn't rerender on delete

I am trying to use hooks and implement a custom hook for handling my data fetching after every update I send to the API.

My custom hook, however, doesn't fire on change like I want it too. Delete has to be clicked twice for it to rerender. Note: I removed some functions from this code as they don't pertain to the question.

    import React, { useState, useEffect } from "react"
    import {Trash} from 'react-bootstrap-icons'
    import InlineEdit from 'react-ions/lib/components/InlineEdit'

    function Board(){
        const [render, setRender] = useState(false)
        const [boards, setBoards] = useState([]);
        const [isEditing, setEdit] = useState(false)
        const [value, setValue] = useState("")
        const[newValue, setNewValue] = useState("")
        const [error, setError] = useState("")

        function useAsyncHook(setState, trigger) {
            const [result] = useState([]);
            const [loading, setLoading] = useState("false");
            useEffect(() => {
                async function fetchList() {
                    try {
                        setLoading("true");
                        const response = await fetch(
                            `http://localhost:8080/api/boards`
                        );
                        const json = await response.json();
                        setState(json)
                    } catch (error) {
                        //console.log(error)
                        setLoading("null");
                    }
                }
            fetchList()
            }, [trigger]);

            return [result, loading];
        }

        useAsyncHook(setBoards, render)

        const handleDelete = (id) => {
            console.log("delete clicked")
            setLoading(true);
            fetch(`http://localhost:8080/api/boards/` + id, {
                method: "DELETE",
                headers: {
                    "Content-Type": "application/json"
                },
            })
            setRender (!render)
        }

       return(
        <div>
            <ul>

                {boards.map(board => (
                <li key={board.id}>
                        <InlineEdit value={board.size} isEditing={isEditing} changeCallback={(event)=>handleSave (event, board.id)} />
                        <Trash onClick={()=>handleDelete(board.id)}/>
                    </li>
            </ul>
        </div>
        );

    }

    export default Board
like image 345
Nika Bo Avatar asked Nov 17 '25 08:11

Nika Bo


1 Answers

OPTION 1:

Maybe you wanna have a hook that tells you when to fetch the board, right? For example:

const [auxToFetchBoard, setAuxToFetchBoard] = useState(false);

Then, in a useEffect you execute the function fetchBoard everytime that hook changes:

useEffect(fetchBoard, [auxToFetchBoard]);

Finally, in your handleDelete function, if your delete request returns correctly, you have to update auxToFetchBoard. Something like this:

const handleDelete = (id) => {
    setIsLoading(true);
    setError("");

    fetch(yourURL, yourOptions)
        .then(res => {
            // check if response is correct and
            setIsLoading(false);
            setAuxToFetchBoard(!auxToFetchBoard);
        })
        .catch(() => {
            setIsLoading(false);
            setError("Error while deleting stuff");
        });
};

Note: I changed the names of isLoading and setIsLoading because they are more explicit.

OPTION 2:

Instead of fetching the board again and again, you can update your board (in this case your code would be in 8th line inside the handleDeletefunction).

Hope it helps.

like image 176
Nico Diz Avatar answered Nov 20 '25 05:11

Nico Diz



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!