And*_*eff 6 reactjs redux react-redux reselect react-hooks
我在我的 React 项目中使用 reselect lib。
我已经创建了Posts
工作正常的选择器。这是代码
// selectors.ts
const getPosts = (state: RootState) => state.posts.posts;
export const getPostsSelector = createSelector(getPosts, (posts) => posts);
Run Code Online (Sandbox Code Playgroud)
我在我的页面上这样称呼它
// SomePage.tsx
const posts = useSelector(getPostsSelector);
Run Code Online (Sandbox Code Playgroud)
现在我需要通过 id 获取帖子。我想这样做:
// selectors.ts
const getPostDetail = (state: RootState) =>
state.posts.posts.entities[ID];
export const getPostsById = createSelector(
getPostDetail,
(detail) => detail
);
Run Code Online (Sandbox Code Playgroud)
并在页面上调用:
const PostDetail = useSelector(getPostsById);
Run Code Online (Sandbox Code Playgroud)
我有两个问题:
按具体情况来选择并不是正确的做法id
。该useSelector
钩子不允许将更多内容传递state
给选择器。
一个迂回的解决方案可能是将specific
帖子id
也存储到状态中并选择它。缺点是该帖子在初始渲染时不可用,您需要分派(从useEffect
挂钩或回调)一个操作来存储您想要的帖子id
。
const getPostById = createSelector(
[getPostsSelector, getPostId],
(posts, id) => posts.find(post => post.id === id);
);
Run Code Online (Sandbox Code Playgroud)
用法:
const postById = useSelector(getPostById);
...
dispatch(setPostId(postId)); // store the id
Run Code Online (Sandbox Code Playgroud)
由于您无法创建一个选择器来id
直接返回特定帖子,因此我建议创建一个选择器来返回帖子的派生状态对象,这有助于更快的查找,即地图或对象。
例子:
const postDetailMap = createSelector(
[getPosts],
posts => posts.reduce((posts, post) => ({
...posts,
[post.id]: post,
}), {}),
);
Run Code Online (Sandbox Code Playgroud)
用法:
const postsMap = useSelector(postDetailMap);
const specificPost = postMap[postId];
Run Code Online (Sandbox Code Playgroud)
不过,您也许可以将其抽象为自定义挂钩。
const useGetPostById = id => {
const postsMap = useSelector(postDetailMap);
return postsMap[id];
}
Run Code Online (Sandbox Code Playgroud)
用法:
const post = useGetPostById(postId);
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3611 次 |
最近记录: |