簡體   English   中英

如何根據變量值使 useEffect react 鈎子重新渲染?

[英]How can I make useEffect react hook rerender based on a variable value?

所以我得到了這個組件:

export default function () {
    const [todos, setTodos] = useState([]);


    useEffect(() => {
        function populateTodos () {
            axios.get(`http://localhost:8000/api/all-todos`)
                .then(res => setTodos(res.data))
                .catch(err => console.log(err));
        }

        populateTodos();
    }, []);

    console.log(todos);

    return (
        <div>
            ...
        </div>
    );
}

我正在使用useEffect鈎子從數據庫中獲取所有useEffect ,並且工作正常。 問題是我不知道如何使用useEffect在我對 todos 數組進行修改時觸發重新渲染,例如添加或刪除或更新。 如果我使用todos變量提供useEffect的依賴數組,我會在控制台中得到一個無限循環日志。 如何在todos數組更新時使用useEffect觸發重新渲染?

問題是 useEffect 內部沒有邏輯,請參閱下面的代碼

    const [todos, setTodos] = useState([]);

    useEffect(() => {
        setTodos([1])
    }, [todos])

這也會產生無限循環。 但我們總是給予相同的價值。 問題是當它被更新時,依賴是真的,所以它再次開始執行 useEffect()。 您必須提出一些具體的邏輯,例如更改length ,或者您可以采用如下所示的新狀態

    const [todos, setTodos] = useState([]);
    const [load, setLoad] = useState(false);

    useEffect(() => {
        function populateTodos () {
            axios.get(`http://localhost:8000/api/all-todos`)
                .then(res => setTodos(res.data))
                .catch(err => console.log(err));
        }

        populateTodos();
    }, [load])

    console.log(todos)
    return (
        <div>
            <button
            onClick={() => {
                todos.push(1)
                setLoad(!load)
            }}
            >cilck</button>
        </div>
    );

可以通過在父組件中獲取 todos提升狀態,然后將結果作為 prop 傳遞給 useEffect 依賴於它的子組件。 任何 CRUD 操作都必須在父組件中調用才能更新列表(但您可以通過將這些函數傳遞給子組件來觸發子組件的修改)。

否則,這也將是 Redux 的一個很好的應用程序。 您將能夠使用 Redux fetch 操作初始化組件,以使用在任何組件上完成的所有 CRUD 操作填充存儲,並通過修改減速器的 API 響應更新存儲。 然后你可以使用 store 作為 useEffect 依賴來更新組件的本地 todo 狀態。

// State
const [todos, setTodos] = useState(null);
// Redux Stores 
const todoStore = useSelector(state => state.todoStore);
// Redux Dispatch
const dispatch = useDispatch();
// Lifecycle: initialize the component's todolist
useEffect(() => {
    if (!todos) {
        // your Redux Action to call the API fetch & modify the store
        dispatch(fetchTodos); 
    }
}, [dispatch, todos]
// Lifecycle: update the todolist based on changes in the store
// (in this case I assume the data is populated into todoStore.items)
useEffect(() => {
    if (todoStore.items.length > 0) {
        setTodos(todoStore);
    }
}, [todoStore.items]

return {
    <div>{ todos.map((todo, index) => <li key={'todo_'+index}>{todo}</li>) }</div>
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM