useSWR在获取的数据上丢弃更改

huangapple go评论66阅读模式
英文:

useSWR discard changes on fetched data

问题

似乎我不太理解如何在React中使用useSWR。我有以下简化的问题:

我使用useSWR获取数据并更改该对象的标题。如果我不想保存数据并再次返回到这个页面,useSWR会显示旧数据,但标题已更改。尽管正确的数据已被获取(我可以在开发者控制台中看到),但该函数会返回编辑后的对象,这是我之前更改过的。在任何我使用相同useSWR调用的地方,我都会得到更改后的对象。

我应该如何在React中使用useSWR,有哪些良好的实践?我是否应该创建一个副本,然后只更改副本?

这里是一个缩短示例的代码片段,其中包含此问题:

英文:

apparently I don't quite understand how to work with useSWR and React. I have the following simplified problem:

I fetch data using uswSWR and change the title of this object. If I don't want to save the data and navigate back and to this page again, useSWR shows the old data, with changed title. Although the correct data is fetched (which I can see in the developer console), the function returns the edited object, which I changed before. Everywhere where I use the same useSWR-call, I get the changed object.

How should I work with useSWR in React, what are good practices? Should I make a copy and only change the copy?

Here a code snipped of a shortened example with this problem:

import { useRouter } from "next/router";

import type { NextPage } from 'next';
import offerService from "services/offer.service";
import useSWR from "swr";
import Offer from "types/offer.type";
import { Box, TextField, Typography } from "@mui/material";

const EditOfferPage: NextPage = () => {
  const router = useRouter();
  
  const { offerId } = router.query;

  // loading the offer object using SWR
  const { data: offer, error } = useSWR<Offer>(
    "getOfferById", () => offerService.getOfferById(parseInt(String(offerId))).then((res) => res.data)
  );
  
  if (error) return <Typography>Error</Typography>;
  if (!offer) return <Typography>Loading...</Typography>;

  const handleChange = (event:  React.ChangeEvent<HTMLInputElement>) => {
    // changing title of offer object
    offer.title = event.target.value;
  }

  return (
    <Box>
      <TextField
            id="test-textfield"
            value={offer.title}
            onChange={handleChange}
          />
    </Box>
  );
};

export default EditOfferPage;

答案1

得分: 1

In

useSWR<Offer>(
  "getOfferById",
  () => offerService.getOfferById(parseInt(String(offerId))).then((res) => res.data)
  );

你使用相同的缓存键 getOfferById,即使结果在 offerId 上有所不同。

请使用如下方式:

useSWR<Offer>(
  `getOfferById/${offerId}`,
  () => offerService.getOfferById(parseInt(String(offerId))).then((res) => res.data)
);

或者更好的做法是使用数组键,并让提取函数知道如何处理

function fetchOfferById([_, offerId]) {
  return offerService.getOfferById(parseInt(String(offerId))).then((res) => res.data);
}

// ...

useSWR<Offer>(['getOfferById', offerId], fetchOfferById);
英文:

In

useSWR<Offer>(
  "getOfferById",
  () => offerService.getOfferById(parseInt(String(offerId))).then((res) => res.data)
  );

you're using the same cache key getOfferById even if the result varies over offerId.

Do e.g.

useSWR<Offer>(
  `getOfferById/${offerId}`,
  () => offerService.getOfferById(parseInt(String(offerId))).then((res) => res.data)
);

or better yet use an array key and have the fetcher function know what to do:

function fetchOfferById([_, offerId]) {
  return offerService.getOfferById(parseInt(String(offerId))).then((res) => res.data);
}

// ...

useSWR<Offer>(['getOfferById', offerId], fetchOfferById);

答案2

得分: -2

你所面临的问题是数据重新验证。

我建议你查看以下资源:

https://swr.vercel.app/docs/revalidation

https://koba04.medium.com/revalidating-options-of-swr-4d9f08bee813

英文:

The problem you are facing is with revalidating the data

I recommend you go through the below resources:

https://swr.vercel.app/docs/revalidation

https://koba04.medium.com/revalidating-options-of-swr-4d9f08bee813

huangapple
  • 本文由 发表于 2023年2月6日 15:00:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/75358224.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定