【问题标题】:React Context - Post Like / Unlike featureReact Context - 发布喜欢/不喜欢的功能
【发布时间】:2020-08-31 15:28:08
【问题描述】:

我正在使用 React 上下文构建类似/不像功能的帖子,但我不知道如何在 reducer 中更新 UI。目前当我点击喜欢/不喜欢按钮时,ui不会立即更新,必须刷新页面才能看到更新。

后端逻辑

exports.likePost = async (req, res) => {
  try {
    const result = await Post.findByIdAndUpdate(
      req.body.postId,
      {
        $push: { likes: req.body.userId },
      },
      { new: true }
    );

    return res.json(result);
  } catch (err) {
    console.log(err.message);
  }
};

exports.unlikePost = async (req, res) => {
  try {
    const result = await Post.findByIdAndUpdate(
      req.body.postId,
      {
        $pull: { likes: req.body.userId },
      },
      { new: true }
    );

    return res.json(result);
  } catch (err) {
    console.log(err.message);
  }
};

组件

 {post.likes.includes(loggedInUser._id) ? (
            <IconButton
              color="secondary"
              component="span"
              onClick={() => unlikePost(loggedInUser._id, post._id)}
            >
              <Like />
            </IconButton>
          ) : (
            <IconButton
              color="secondary"
              component="span"
              onClick={() => likePost(loggedInUser._id, post._id)}
            >
              <Unlike />
            </IconButton>
          )}

上下文

const initialState = {
  posts: [],
};

// Like post
  const likePost = async (userId, postId) => {
    try {
      const res = await axios.put(
        `/api/posts/like`,
        { userId, postId },
        {
          headers: {
            "Content-Type": "application/json",
            Authorization: `Bearer ${localStorage.getItem("token")}`,
          },
        }
      );
      dispatch({ type: "LIKE_POST", payload: res.data });
    } catch (err) {
      console.log(err);
    }
  };

  // Unlike post
  const unlikePost = async (userId, postId) => {
    try {
      const res = await axios.put(
        `/api/posts/unlike`,
        { userId, postId },
        {
          headers: {
            "Content-Type": "application/json",
            Authorization: `Bearer ${localStorage.getItem("token")}`,
          },
        }
      );
      dispatch({ type: "UNLIKE_POST", payload: res.data });
    } catch (err) {
      console.log(err);
    }
  };

减速器

case "LIKE_POST":
      return {
        ...state,
        posts: // ???
        ),
      };
case "UNLIKE_POST":
      return {
        ...state,
        posts: // ???,
      };

reducer 的逻辑应该是什么?

【问题讨论】:

    标签: reactjs react-context use-reducer


    【解决方案1】:

    类似这样的:

    case "LIKE_POST":
      return {
        ...state,
        like: action.likeValue,
      };
    
    case "UNLIKE_POST":
      return {
        ...state,
        unlike: action.unlikeValue,
      };
    

    当你想改变值时:

    dispatch({ type: "LIKE_POST", likeValue: res.data });
    dispatch({ type: "UNLIKE_POST", unlikeValue: res.data });
    
    

    在你的初始状态:

    const initialState = {
      posts: [],
      like: [],
      unlike: [],
    };
    

    这是一个很好的解释,对我有帮助:link

    【讨论】:

    • 成功了。谢谢你。可以说我也会添加 cmets 功能。那么我是否也必须在 initialState 中将其定义为空数组? state中加like、like、cmets等可以吗?
    • 我很高兴它成功了。如果您只需要一个组件中的变量(例如 cmets),那么您可以在组件的状态中添加它。如果您在子/父组件中需要它,那么您可以使用 props 传递它,或者您可以在初始状态下定义它。如果您在另一个组件中需要它,则将其定义为初始状态并使用减速器进行设置。这样,上下文 API 使该变量在您需要的每个组件中都可用。您可以根据需要在初始状态中定义任意数量的变量,它们可以来自您想要的每种类型(数组、对象、字符串、数字...)。
    猜你喜欢
    • 1970-01-01
    • 2018-06-26
    • 2021-07-10
    • 2020-10-31
    • 1970-01-01
    • 2019-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多