gpt4 book ai didi

javascript - 使用redux,如何避免在进行新的API调用之前渲染旧的状态数据?

转载 作者:行者123 更新时间:2023-12-03 07:04:17 24 4
gpt4 key购买 nike

我刚开始用 redux 做一些实验和 react-redux .

注:我正在使用 Hooks,所以我正在使用 useSelector()useDispatch()来自 react-redux 的自定义 Hook .

想象一下,我有一些状态可以得到 blogPost来自基于 slug 的数据库.

我的 state.blogPost:

{
loading: false, // TRUE while fetching
error: null, // TO keep network errors
blogPost: null // TO keep the blogPost
}

BlogPostContainer.js

我在 useEffect 内分派(dispatch) Action 和异步调用.

注1:我正在手动执行异步工作,因为我没有使用 redux-thunk然而。

注2:我正在使用 react-router-dom所以蛞蝓来自 props.match.params.slug .

示例: myApp.net/blog/some-blog-post-slug

// ...

const { loading, error, blogPost } = useSelector(state => state.blogPost);
const dispatch = useDispatch();

useEffect(() => {

dispatch({ type: "GET_BLOGPOST_START", payload: props.match.params.slug }); // START ACTION

mockAPI(props.match.params.slug)

.then((result) => {
dispatch({ type: "GET_BLOGPOST_SUCCESS", payload: result }); // SUCCESS ACTION
})

.catch((err) => {
dispatch({ type: "GET_BLOGPOST_FAIL", payload: err }); // FAIL ACTION
})

}, [dispatch,props.match.params.slug]);

// RETURN STATEMENT

return (
loading ?
<div>Loading...</div>
: error ?
<ErrorPage/>
: <BlogPostPage blogPost={blogPost}/>
);


问题

这对于第一个加载的 blogPost 工作正常(因为此时状态完全为空)。

现在想象一下,我回到主页点击另一个 blogPost。

从第二次开始,当我的 BlogPostContainer渲染时,我的状态中已经存在一些东西(上一次 blogPost slug 上次加载的 blogPosterror)。

因此, 我在 之前的屏幕上看到了该信息的闪烁。我的 useEffect运行。当它运行时, loading将由 GET_BLOGPOST_START 设置为 true行动,我会看到加载。

我想立即看到加载页面。没有任何旧状态数据闪烁。

人们在使用 redux 时通常如何处理这个问题?
  • 我需要一个本地 loading状态?
  • 我是否应该派出一个 Action 来转向 loadingtrue当我的组件卸载时?所以它已经是 true当我的组件为下一个 slug 再次挂载时?
  • 我应该使用 useLayoutEffect所以效果会渲染前运行我不会看到闪烁? (它有效,但感觉不对)。
  • 这种情况的最佳解决方案是什么?


  • 额外的

    我的 reducer :
    const initialState = {
    loading: false,
    error: null,
    blogPost: null
    };

    function getBlogPostReducer(state = initialState, action) {
    switch (action.type) {
    case "GET_BLOGPOST_START": // SET LOADING TO TRUE
    return {
    ...initialState,
    loading: true
    };
    case "GET_BLOGPOST_SUCCESS": // SET BLOGPOST and LOADING TO FALSE
    return {
    ...initialState,
    loading: false,
    blogPost: action.payload
    };
    case "GET_BLOGPOST_FAIL": // SET ERROR and LOADING TO FALSE
    return {
    ...initialState,
    loading: false,
    error: action.payload
    };
    default:
    return state;
    }
    }

    export default getBlogPostReducer;

    最佳答案

    useEffect返回一个清理函数,该函数将在组件卸载时调度“清除博客文章”操作:

    useEffect(() => {
    dispatch({ type: "GET_BLOGPOST_START", payload: props.match.params.slug }); // START ACTION

    mockAPI(props.match.params.slug)

    .then((result) => {
    dispatch({ type: "GET_BLOGPOST_SUCCESS", payload: result }); // SUCCESS ACTION
    })

    .catch((err) => {
    dispatch({ type: "GET_BLOGPOST_FAIL", payload: err }); // FAIL ACTION
    })

    return () => dispatch({ type: "CLEAR_BLOGPOST" });

    }, [dispatch,props.match.params.slug]);
    并且 reducer 处理程序应该同时删除 errorblogpost来自该州的条目:
    case "CLEAR_BLOGPOST":
    return initialState;

    关于javascript - 使用redux,如何避免在进行新的API调用之前渲染旧的状态数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59592378/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com