I'm struggling to understand what could be causing a slow response from the server, upwards of 2 seconds for a simple patch. I've gone ahead and posted an example to help better illustrate the problem. Right now if you swipe right on a card, it will kick off a saveLike and saveVote. Both will fetch data from Card.js about what card you swiped right on and your userID to save to. I'm running next.js with sanity.io, using yarn dev and yarn start respectively. Even insight on how to debug what could be causing a long wait period for a query would be super helpful long term
#context
const handleRightSwipe = async (cardData, votesData) => {
try {
await fetch('/api/saveLike', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
likedCards: cardData,
currentUser: "abc123",
}),
})
// deduct one incrementally
let votesAmount = votesData--
try {
await fetch('/api/saveVote', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
_id: "abc123",
votes: votesAmount
}),
})
} catch (error) {
console.error(error)
}
// set vote tally the latest amount
setVotesData(votesAmount)
// request vote tally be updated on the client side
requestVoteAmount(userID)
} catch (error) {
console.error(error)
}
}
# saveVote
import { client } from '../../lib/sanity'
const saveVote = async (req, res) => {
try {
await client
.patch(req.body._id).set({votes:req.body.votes}).commit()
res.status(200).send({ message: 'success' })
} catch (error) {
res.status(500).send({ message: 'error', data: error.message })
}
}
export default saveVote
#saveLike
import { client } from '../../lib/sanity'
const saveLike = async (req, res) => {
try {
await client
.patch(req.body.likedCards._id)
.setIfMissing({'likes': []})
.insert('after', 'likes[-1]',[
{
_ref: req.body.currentUser,
_type: "reference",
},
])
.commit({
autoGenerateArrayKeys: true,
})
res.status(200).send({ message: 'success' })
} catch (error) {
res.status(500).send({ message: 'error', data: error.message })
}
}
#Card
import React, { useState, useMemo, useContext, useRef, useEffect } from 'react'
import { Context} from '../context/Context'
import TCard from 'react-tinder-card'
const Card = () => {
const { cardsData, votesData } = useContext(Context)
const { handleRightSwipe, handleLeftSwipe, currentAccountAddress } = useContext(Context)
const [currentIndex, setCurrentIndex] = useState(cardsData.length - 1)
const currentIndexRef = useRef(currentIndex)
const childRefs = useMemo(
() =>
Array(cardsData.length)
.fill(0)
.map((i) => React.createRef()),
[cardsData.length]
)
const updateCurrentIndex = (val) => {
setCurrentIndex(val)
currentIndexRef.current = val
}
const canVote = votesData > 0
const swiped = (direction, card, index) => {
if (!canVote) return
if (votesData > 0) {
if (direction === 'right') {
const voterAmount = votesData--
updateCurrentIndex(index - 1)
handleRightSwipe(card, currentAccountAddress, voterAmount)
}
if (direction === 'left') {
const voterAmount = votesData--
updateCurrentIndex(index - 1)
handleLeftSwipe(card, currentAccountAddress, voterAmount)
}
}
else {
}
}
const outOfFrame = (idx) => {
currentIndexRef.current >= idx && childRefs[idx].current.restoreCard()
}
return (
<div>
{
<div>
{cardsData.map((card, index) => (
<TCard
card={card}
key={card.name}
ref={childRefs[index]}
preventSwipe={['up', 'down']}
onCardLeftScreen={() => outOfFrame(card.name, index)}
onSwipe={(dir) => swiped(dir, card, index)}>
<div
style={{ backgroundImage: `url('${card.imageUrl}')`
>
</div>
</TCard> ))}
</div>
}
</div>
)
}
export default Card
The mutation API has a visibility
parameter that defaults to sync
. This means it will wait for the data to be ready to be queried before it returns - which you quite often do not need (I consider "update then refetch" an antipattern).
To speed up your mutations, use the async
visibility. In your code, you can do this by passing visibility: 'async'
in your commit()
calls:
await client
.patch(req.body.likedCards._id)
.setIfMissing({'likes': []})
.insert('after', 'likes[-1]', [
{
_ref: req.body.currentUser,
_type: "reference",
},
])
.commit({
autoGenerateArrayKeys: true,
visibility: 'async',
})