【发布时间】:2020-04-22 19:58:56
【问题描述】:
我刚刚开始用redux 和react-redux 做一些实验。
注意:我正在使用 Hooks,所以我使用来自 react-redux 的 useSelector() 和 useDispatch() 自定义挂钩。
想象一下,我有一些状态可以根据slug 从数据库中获取blogPost。
我的 state.blogPost:
{
loading: false, // TRUE while fetching
error: null, // TO keep network errors
blogPost: null // TO keep the blogPost
}
BlogPostContainer.js
我在 useEffect 内调度操作和异步调用。
注意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 工作正常(因为此时状态完全为空)。
现在想象一下,我回到主页点击另一篇博文。
从第二次开始,当我的 BlogPostContainer 呈现时,我的状态中已经存在一些东西(blogPost 或 error,上次为上一个 blogPost slug 加载)。
因此,在我的useEffect 运行之前,我看到屏幕上显示了该信息的闪烁。当它运行时,loading 将被 GET_BLOGPOST_START 操作设置为 true,我会看到加载。
我想立即查看加载页面。没有任何旧状态数据闪烁。
人们在使用 redux 时通常如何处理这个问题?
我需要 本地
loading状态吗?当我的组件卸载时,我是否应该分派一个操作将
loading转换为true?所以当我的组件再次为下一个slug挂载时,它已经是true?我是否应该使用
useLayoutEffect,这样效果才会在渲染前运行并且我不会看到闪烁? (有效,但感觉不对)。这种情况的最佳解决方案是什么?
额外
我的减速机:
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;
【问题讨论】:
标签: javascript reactjs redux react-redux react-hooks