如何根据 useState 显示数据库中递增的条目?

问题描述 投票:0回答:1

我在 ReactJS 中有这个功能。当用户打开主页时,会显示数据库中的良好条目数。但是当我刷新页面时,计数从 0+1 开始。哪里错了?

const [user, setUser] = useState({ id: "", name: "", email: "", entries: 0, joined: "", });

const onButtonSubmit = () => {
  setImageUrl(input);
  fetch("http://localhost:3000/imageurl", {
      method: "post",
      headers: {
        "Content-Type": "application/json",
        Authorization: "bearer " + localStorage.getItem("token"),
      },
      body: JSON.stringify({
        input: input,
      }),
    })
    .then((response) => response.json())
    .then((response) => {
      if (response) {
        setUser((prev) => {
          localStorage.setItem(
            "user",
            JSON.stringify({
              ...JSON.parse(localStorage.getItem("user")),
              entries: prev.entries + 1,
            })
          );
          return { ...prev, entries: prev.entries + 1 };
        });
      }
      displayPredictions(handleApiPredictions(response));
    })
    .catch((err) => console.log(err));
};
javascript reactjs counting
1个回答
0
投票

发生了什么事?

const [user, setUser] = useState({ id: "", name: "", email: "", entries: 0, joined: "", });

首先,您的状态在页面加载时初始化

entries: 0
.

然后:

JSON.stringify({
  ...JSON.parse(localStorage.getItem("user")),
  entries: prev.entries + 1,
})

您从本地存储中获取该项目。并将其与之前的状态合并,即使用

entries: 0
.

初始化的状态

所以你基本上是这样做的。

{
  ...({ entries: 123 }),
  entries: ({ entries: 0 }).entries + 1
}

所以从

entries
开始的第二个
0
正在覆盖第一个。


一个简单的修复

要修复它,只需从本地存储初始化您的状态即可。

const [user, setUser] = useState(
  localStorage.getItem('user') ??
  { id: "", name: "", email: "", entries: 0, joined: "", }
);

如果本地存储中没有任何内容,这将回到初始状态。

现在在你的 setter 中,你根本不需要从本地存储中获取。

setUser((prev) => {
  const newUserState = { ...prev, entries: prev.entries + 1 }
  localStorage.setItem("user", JSON.stringify(newUserState))
  return newUserState
})

更好的方法

不建议让你的状态设置器直接产生副作用(比如写入本地存储)。如果您从其他函数更新此对象怎么办?您还必须复制代码以保存到本地存储。

更正确的方法是使用效果使本地存储与任何来源的任何更改保持同步。

可能看起来像这样:

// Initialize state with local storage item, or fallback.
// Use a function for initial state so that fetching from
// local storage only happens once.
const [user, setUser] = useState(() =>
  localStorage.getItem('user') ??
  { id: "", name: "", email: "", entries: 0, joined: "", }
);

// Writes to local storage after the `user` state is set.
useEffect(() => {
  localStorage.setItem("user", JSON.stringify(user))
}, [user])

// Now when you set the state, all you need to do is:
setUser((prev) => {
  return { ...prev, entries: prev.entries + 1 };
});
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.