React Redux Toolkit 访问对象数组中的值

React Redux Toolkit access value inside array of objects

组件:

const postState = useSelector((state: RootState) => state.postsSlice.posts);

 {postState?.map((post) => {
                return (
                  <PostCard
                    key={post.id}
                    title={post.title}
                    description={post.body}
                    user={post.user}
                    voteCount={post.upvotes - post.downvotes}
                    onClick={() =>
                      navigate(`/posts/${subredditId}/post/${post.id}`)
                    }
                  />
                );
              })}

我正在使用 React typescript 开发一个 reddit 克隆项目。我将 api 中的数据作为以下类型的对象数组:

export type Posts = Post[];

export type Post = {
  id: string;
  title: string;
  user: string;
  body: string;
  upvotes: number;
  downvotes: number;
};

然后我像这样将数据存储在 redux 工具包中:

type PostsArray = {
  posts: Array<Post>;
};

const initialState: PostsArray = { posts: [] };

const PostsSlice = createSlice({
  name: "PostsSlice",
  initialState: initialState,
  reducers: {
    setPostsData(state, action: PayloadAction<Array<Post>>) {
      state.posts = action.payload;
    },
  },
});
export const { setPostsData } = PostsSlice.actions;
export default PostsSlice.reducer;

当我在我的组件中映射对象时,我通过从赞成票中减去反对票来显示 reddit 投票计数。 我想要做的是能够对不同的 post 投赞成票和反对票,并将该投票存储在 redux 中。我考虑了增加赞成票的派遣和增加反对票的派遣。但我不知道该怎么做。我不知道如何在 redux 中访问特定 post 的赞成票。有什么想法吗?

对于这种情况,您可以添加一个减速器来获取 post id 并使用传递给操作负载的值更新它,如下所示:

减速器

const PostSlice = createSlice({
  name: "PostSlice",
  initialState: initialState,
  reducers: {
    setPostsData(state, action: PayloadAction<Array<Post>>) {
      state.posts = action.payload;
    },
    // reducer to change the vote count
    updateVoteCount(
      state,
      // in the vote payload you can use an enumerate 
     // if you want to avoid typos
      action: PayloadAction<{ id: string; vote: string }>
    ) {
      // find the post by id
      const post = state.posts.find((post) => post.id === action.payload.id);
      if (!post) return;
      if (action.payload.vote === "up") {
        // update the vote depending on payload vote parameter
        post.upvotes += 1;
      }
      if (action.payload.vote === "down") {
        post.downvotes += 1;
      }
    }
  }
});

明信片

因为你没有提供你的PostCard的代码,我举个简单的例子给你看:

const PostCard = (props: PostCardProps) => {
  const dispatch = useDispatch();
  return (
    <div>
      <h2>{props.title}</h2>
      <p>{props.description}</p>
      <p>{props.user}</p>
      <p>{props.voteCount}</p>
      <div>
        <button
          onClick={() =>
            //Dispatch the action with vote "up"
            dispatch(updateVoteCount({ id: props.id, vote: "up" }))
          }
        >
          Up vote
        </button>
        <button
          onClick={() =>
            // dispatch with vote "down"
            dispatch(updateVoteCount({ id: props.id, vote: "down" }))
          }
        >
          Down vote
        </button>
      </div>
    </div>
  );
};
export default PostCard;

请检查 working example