为啥我没有取回 useState 的新值 - React.JS?

Posted

技术标签:

【中文标题】为啥我没有取回 useState 的新值 - React.JS?【英文标题】:Why I'm not getting back the new value of useState - React.JS?为什么我没有取回 useState 的新值 - React.JS? 【发布时间】:2021-02-13 14:42:16 【问题描述】:

在 setVotedPosts([...previousVotedPosts, postId]); 行中

我正在尝试获取以前的 votedPosts 值,但我正在取回最新的值。

完整代码:https://github.com/silvertechguy/reddit-clone/blob/main/src/components/vote-buttons.js

应用直播:https://reddit-clone-official.vercel.app/

const VoteButtons = ( post ) => 
  const [isVoting, setVoting] = useState(false);
  const [votedPosts, setVotedPosts] = useState([]);

  useEffect(() => 
    const votesFromLocalStorage =
      JSON.parse(localStorage.getItem("votes")) || [];

    setVotedPosts(votesFromLocalStorage);
  , []);

  const handleDisablingOfVoting = (postId) => 
    const previousVotedPosts = votedPosts;
    setVotedPosts([...previousVotedPosts, postId]);

    localStorage.setItem(
      "votes",
      JSON.stringify([...previousVotedPosts, postId])
    );
  ;

  const handleClick = async (type) => 
    setVoting(true);

    // Do calculation to save the vote.
    let upVotesCount = post.upVotesCount;
    let downVotesCount = post.downVotesCount;

    const date = new Date();

    if (type === "upvote") 
      upVotesCount = upVotesCount + 1;
     else 
      downVotesCount = downVotesCount + 1;
    

    await db.collection("posts").doc(post.id).set(
      title: post.title,
      upVotesCount,
      downVotesCount,
      createdAt: post.createdAt,
      updatedAt: date.toUTCString(),
    );

    // Disable the voting button once the voting is successful.
    handleDisablingOfVoting(post.id);

    setVoting(false);
  ;

  const checkIfPostIsAlreadyVoted = () => votedPosts.includes(post.id);

【问题讨论】:

previousVotedPosts - 这将在您调用 setVotedPosts 函数更新状态之前引用状态值。您尝试访问 votedPosts 的哪个先前值? 在我更新状态 (setVotedPosts) 并尝试获取更新后的状态后,我总是返回一个空数组。 状态是异步更新的,组件只有在重新渲染后才能看到更新后的状态。如果要记录更新的状态,请使用 useEffect 钩子。 有什么办法可以防止 useEffect 钩子在第一次运行? 我想在每次 votedPosts 更改时运行 useEffect,方法是将它添加到 useEffect 的依赖数组中。但我不想第一次运行它。 【参考方案1】:

问题

const previousVotedPosts = votedPosts;

javascript 中,数组是引用类型,因此您不能只使用 = 创建数组的新副本。

试试这个解决方案

使用扩展语法克隆数组(...)。

  const handleDisablingOfVoting = (postId) => 
    const previousVotedPosts = [...votedPosts];
    setVotedPosts([...previousVotedPosts, postId]);

    localStorage.setItem(
      "votes",
      JSON.stringify([...previousVotedPosts, postId])
    );
  ;

【讨论】:

感谢您的回复。每次我尝试向 localStorage 添加一些内容时,新值都会覆盖 localStorage 中的现有值。这是我的主要问题,也是我在这里提出主要问题的原因。

以上是关于为啥我没有取回 useState 的新值 - React.JS?的主要内容,如果未能解决你的问题,请参考以下文章

可编辑的新值不保存到数据库

在道具更改时重新渲染功能组件

为啥这不会一遍又一遍地返回一个新值?爪哇

当 Publisher 参数没有要发出的任何新值时,为啥会调用 SwiftUI View 上的 onReceive 块?

在“beforeChange”订阅中获取可观察的新值

直接更新 useState 对象键? [复制]