简体   繁体   中英

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

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 handleDelete function).

Hope it helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM