首页 > 解决方案 > 使用 useReducer 在状态更改时不重新渲染组件功能

问题描述

我正在使用 useReducer 来管理状态,并且想要一个功能,即在按下“加载”后,程序会在获取数据并呈现更新状态之前显示“正在加载 ...”3 秒,但“正在加载 ...”仍然存在并且该组件不会重新渲染。我放置了 console.logs 以确认状态更改确实发生了,那么为什么组件没有重新渲染?请帮忙。以下是日志打印输出:

在此处输入图像描述

我的组件功能如下,完整代码在 github 中:https ://github.com/yanichik/react-course/tree/main/full-course/practice/use-reduce

import { useReducer, useEffect } from "react";
import axios from "axios";

function reducer(state, action) {
    console.log("start of state:", state);
    if (action.type === "stopGetArticle") {
        state = { ...state, loading: false, data: null, error: null };
    } else if (action.type === "getArticleStart") {
        state = { ...state, loading: true };
    } else if (action.type === "getArticleSuccess") {
        console.log("pre-timeout state", state);
        setTimeout(() => {
            state = { ...state, loading: false, data: action.payload };
            console.log("post-timeout state", state);
        }, 3000);
    } else if (action.type === "getArticleFail") {
        state = { ...state, loading: false };
    }
    console.log("end of state:", state);
    return state;
}

const initialState = {
    loading: false,
    error: null,
    data: null,
};

function App() {
    const [state, dispatch] = useReducer(reducer, initialState);
    useEffect(() => {
        axios
            .get("http://localhost:3004/posts/1")
            .then((res) => {
                console.log("res", res);
                dispatch({ type: "getArticleSuccess", payload: res.data });
            })
            .catch((err) => {
                dispatch({ type: "getArticleFail" });
            });
    }, [state.loading]);

    return (
        <div className="App">
            <div>
                <button
                    onClick={() => {
                        dispatch({ type: "getArticleStart" });
                    }}
                >
                    Load
                </button>
                <button
                    onClick={() => {
                        dispatch({ type: "stopGetArticle" });
                    }}
                >
                    UnLoad
                </button>
            </div>
            {state.loading && <div>Loading ...</div>}
            {state.data && <div>{state.data.title}</div>}
        </div>
    );
}

export default App;

标签: javascriptreactjs

解决方案


推荐阅读