触发缓存以确保数据正确问题 - swr hook - next.js(使用打字稿)
Trigger cache to make sure data is right problem - swr hook - next.js ( with typescript )
在我的 next.js 应用程序中,我使用 swr 挂钩,因为它提供缓存和实时更新,这对我的项目(facebook 克隆)来说非常棒,但是,有一个问题。
问题是,在我的出版物中,我将它们与 getStaticProps 一起获取,并且我只是映射数组和所有很棒的东西,但是,当我执行某个操作时,例如,喜欢 post,或评论 post,我改变缓存,我认为这样做的目的是询问服务器缓存中的信息是否正确。
但是,它真正做的是,它进行了另一个 API 调用,问题是,如果我喜欢一个出版物,在调用 API 为了确保缓存中的一切都正确,如果有 30 个新出版物,它们将出现在屏幕上,我不希望这样,我希望屏幕上的用户在开始时请求的酒吧,想象一下评论post,然后有 50 个新的 post 所以你丢失了你评论的 post...
让我向您展示一些我的代码。
首先,让我向您展示我的 posts 接口
// 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[];
};
这是我打电话获取所有 posts
的地方
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,如果有新的 post 或其他内容,它将出现在屏幕上,我只想保留我拥有的 post 或添加新的,如果我是创建它们的人。
所以,假设我会喜欢 post
一切都很好而且很快,但是,在确保数据正确之后,另一个 post 会出现,因为另一个用户创建了它
有没有办法在不再次调用 API 的情况下确保数据正确,这会在屏幕上添加更多 post?
我是这个 swr hook 的新手,所以,希望你能帮助我,感谢你抽出时间!
更新
有一种无需重新获取即可更新缓存的方法
很多POSTAPI只会直接return更新数据,所以我们不需要重新验证。这是一个显示“本地变异 - 请求 - 更新”用法的示例:
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
但是,我不知道我应该如何更改我的代码来实现这个,有什么想法吗!?
如果您想更新缓存并确保一切正常,而无需再次调用 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所以它不会再次重新验证,我试过了并且它正在工作,不知道我将来是否会遇到问题,但就知识而言它工作得很好!
在我的 next.js 应用程序中,我使用 swr 挂钩,因为它提供缓存和实时更新,这对我的项目(facebook 克隆)来说非常棒,但是,有一个问题。
问题是,在我的出版物中,我将它们与 getStaticProps 一起获取,并且我只是映射数组和所有很棒的东西,但是,当我执行某个操作时,例如,喜欢 post,或评论 post,我改变缓存,我认为这样做的目的是询问服务器缓存中的信息是否正确。
但是,它真正做的是,它进行了另一个 API 调用,问题是,如果我喜欢一个出版物,在调用 API 为了确保缓存中的一切都正确,如果有 30 个新出版物,它们将出现在屏幕上,我不希望这样,我希望屏幕上的用户在开始时请求的酒吧,想象一下评论post,然后有 50 个新的 post 所以你丢失了你评论的 post...
让我向您展示一些我的代码。
首先,让我向您展示我的 posts 接口
// 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[];
};
这是我打电话获取所有 posts
的地方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,如果有新的 post 或其他内容,它将出现在屏幕上,我只想保留我拥有的 post 或添加新的,如果我是创建它们的人。
所以,假设我会喜欢 post
一切都很好而且很快,但是,在确保数据正确之后,另一个 post 会出现,因为另一个用户创建了它
有没有办法在不再次调用 API 的情况下确保数据正确,这会在屏幕上添加更多 post?
我是这个 swr hook 的新手,所以,希望你能帮助我,感谢你抽出时间!
更新
有一种无需重新获取即可更新缓存的方法
很多POSTAPI只会直接return更新数据,所以我们不需要重新验证。这是一个显示“本地变异 - 请求 - 更新”用法的示例:
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
但是,我不知道我应该如何更改我的代码来实现这个,有什么想法吗!?
如果您想更新缓存并确保一切正常,而无需再次调用 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所以它不会再次重新验证,我试过了并且它正在工作,不知道我将来是否会遇到问题,但就知识而言它工作得很好!