【问题标题】:Trigger cache to make sure data is right problem - swr hook - next.js ( with typescript )触发缓存以确保数据正确问题 - swr 挂钩 - next.js(使用打字稿)
【发布时间】:2021-08-27 23:30:41
【问题描述】:

在我的 next.js 应用程序中,我使用 swr 挂钩,因为它提供缓存和实时更新,这对我的项目(facebook 克隆)来说非常棒,但是,有一个问题。

问题在于,在我的出版物中,我将它们与 getStaticProps 一起获取,并且我只是映射数组和所有内容,但是,当我执行操作时,例如喜欢帖子或评论帖子,我改变缓存,我认为这样做的目的是询问服务器缓存中的信息是否正确。

但是,它真正的作用是,它会进行另一个 API 调用,而问题在于,如果我喜欢发布,在调用 API 以确保缓存中的所有内容都正确之后,如果有 30 个新出版物,它们将出现在屏幕上,我不希望这样,我希望屏幕上的用户在开始时请求的 pubs,想象评论一个帖子,那么有 50 个新帖子,所以你丢失了您评论的帖子...

让我给你看一点我的代码。

首先,让我展示一下我的帖子界面

// Publication representation

export type theLikes = {
  identifier: string;
};

export type theComment = {
  _id?: string;
  body: string;
  name: string;
  perfil?: string;
  identifier: string;
  createdAt: string;
  likesComments?: theLikes[];
};

export interface Ipublication {
  _id?: string;
  body: string;

  photo: string;

  creator: {
    name: string;
    perfil?: string;
    identifier: string;
  };

  likes?: theLikes[];

  comments?: theComment[];

  createdAt: string;
}

export type thePublication = {
  data: Ipublication[];
};

这是我打电话来获取所有帖子的地方

const PublicationsHome = ({ data: allPubs }) => {
  // All pubs

  const { data: Publications }: thePublication = useSWR(
    `${process.env.URL}/api/publication`,
    {
      initialData: allPubs,
      revalidateOnFocus: false
    }
  );


  return (
          <PublicationsHomeHero>
            {/* Show pub */}
            {Publications.map(publication => {
              return <Pubs key={publication._id} publication={publication} />;
            })}
          </PublicationsHomeHero>
        </>
  );
};

export const getStaticProps: GetStaticProps = async () => {
  const { data } = await axios.get(`${process.env.URL}/api/publication`);

  return {
    props: data
  };
};

export default PublicationsHome;

例如,这就是我创建评论、更新缓存、调用 API、然后变异以查看数据是否正确的方式

  // Create comment

  const handleSubmit = async (e: FormEvent<HTMLFormElement>): Promise<void> => {
    e.preventDefault();

    try {

      mutate(
        `${process.env.URL}/api/publication`,
        (allPubs: Ipublication[]) => {
          const currentPub = allPubs.find(f => f === publication);

          const updatePub = allPubs.map(pub =>
            pub._id === currentPub._id
              ? {
                  ...currentPub,
                  comments: [
                    {
                      body: commentBody,
                      createdAt: new Date().toISOString(),
                      identifier: userAuth.user.id,
                      name: userAuth.user.name
                    },
                    ...currentPub.comments
                  ]
                }
              : pub
          );

          return updatePub;
        },
        false
      );
      await createComment(
        { identifier: userAuth.user.id, body: commentBody },
        publication._id
      );
      mutate(`${process.env.URL}/api/publication`);

    } catch (err) {
      mutate(`${process.env.URL}/api/publication`);
    }
  };

现在,正如我已经提到的,在创建评论后,它会再次调用 API,如果有新帖子或其他内容,它将出现在屏幕上,我只想保留我拥有的帖子或如果我是创建它们的人,请添加新的。

所以,假设我会喜欢一个帖子

一切都很棒而且很快,但是,在确保数据正确之后,另一个帖子会出现,因为另一个用户创建了它

有没有一种方法可以确保数据正确,而无需再次调用 API 以将更多帖子添加到屏幕上?

我是这个 swr 钩子的新手,所以,希望你能帮助我,感谢你的时间!

更新

有一种无需重新获取即可更新缓存的方法

很多 POST API 会直接返回更新后的数据,所以我们不需要再次重新验证。这是一个显示“本地变异 - 请求 - 更新”用法的示例:

mutate('/api/user', newUser, false)      // use `false` to mutate without revalidation
mutate('/api/user', updateUser(newUser)) // `updateUser` is a Promise of the request,
                                         // which returns the updated document

但是,我不知道我应该如何更改我的代码来实现这个,任何想法!?

【问题讨论】:

    标签: javascript reactjs typescript next.js swr


    【解决方案1】:

    如果您想更新缓存,并确保一切正常,而不必再次调用 API,这似乎可行

    改变这个

    
    await createComment(
            { identifier: userAuth.user.id, body: commentBody },
            publication._id
          );
    
    mutate(`${process.env.URL}/api/publication`);
    
    

    为此

     mutate(
            `${process.env.URL}/api/publication`,
            async (allPublications: Ipublication[]) => {
              const { data } = await like(
                { identifier: userAuth.user.id },
                publication._id
              );
    
              const updatePub = allPublications.map(pub =>
                pub._id === data._id ? { ...data, likes: data.likes } : pub
              );
    
              return updatePub;
            },
            false
          );
    

    您在那里所做的是使用您将从 API 的操作中接收到的数据更新缓存,并将其放入缓存中,但是,您也必须设置 false 以便它不会重新验证再次,我试过了,它工作正常,不知道我将来是否会遇到问题,但知道它很好用!

    【讨论】:

      猜你喜欢
      • 2021-08-12
      • 2020-12-31
      • 2021-01-24
      • 2021-01-19
      • 2018-04-18
      • 2020-11-11
      • 2019-11-24
      • 2020-07-20
      • 2021-08-02
      相关资源
      最近更新 更多