Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 8525d3f

Browse files
committed
Move the likes count logic to a separate hook
1 parent 332d3c5 commit 8525d3f

File tree

4 files changed

+107
-68
lines changed

4 files changed

+107
-68
lines changed

src/components/HomePageFeed.tsx

Lines changed: 19 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { HomePageFeedUpdateType } from 'src/pages'
1515
import { DateTime } from 'luxon'
1616
import { useMutation, useQuery, useQueryClient } from 'react-query'
1717
import classNames from 'classnames'
18-
import { useEffect, useReducer, useState, useRef } from 'react'
18+
import { useState, useRef } from 'react'
1919
import { signIn, useSession } from 'next-auth/client'
2020
import { User } from 'src/pages/members'
2121
import useFollowUser from './profile/useFollowUser'
@@ -40,28 +40,7 @@ import { scrollToContentWithId } from 'src/utils'
4040
import { IconBrandDiscord } from 'tabler-icons'
4141
import EditUpdate from './goals/EditUpdate'
4242
import toast, { Toaster } from 'react-hot-toast'
43-
44-
type LikeData = {
45-
count: number
46-
hasLiked: boolean
47-
}
48-
const initialState: LikeData = { count: 0, hasLiked: false }
49-
50-
function reducer(state: LikeData, action: { type: string; payload?: any }) {
51-
switch (action.type) {
52-
case 'toggle':
53-
return {
54-
hasLiked: !state.hasLiked,
55-
count: state.hasLiked
56-
? Number(state.count) - 1
57-
: Number(state.count) + 1,
58-
}
59-
case 'set':
60-
return { count: action.payload.count, hasLiked: action.payload.hasLiked }
61-
default:
62-
throw new Error()
63-
}
64-
}
43+
import { useLikes } from './useLikes'
6544

6645
export function HomePageFeedUpdate({
6746
update,
@@ -78,36 +57,6 @@ export function HomePageFeedUpdate({
7857
const { postedBy, createdAt: createdAtInMillis, goal, description } = update
7958
const createdAt = DateTime.fromMillis(createdAtInMillis)
8059
const toastId = useRef('')
81-
const { isLoading, isError, data } = useQuery(
82-
['api/fauna/has-liked', update.id],
83-
() => {
84-
return fetch(`/api/fauna/has-liked`, {
85-
method: 'POST',
86-
headers: {
87-
'Content-Type': 'application/json',
88-
},
89-
body: JSON.stringify({
90-
updateId: update.id,
91-
}),
92-
}).then((res) => res.json())
93-
}
94-
)
95-
const { mutate } = useMutation(() => {
96-
return fetch(`/api/fauna/toggle-like`, {
97-
method: 'POST',
98-
headers: {
99-
'Content-Type': 'application/json',
100-
},
101-
body: JSON.stringify({
102-
updateId: update.id,
103-
}),
104-
}).then((res) => {
105-
if (!res.ok) {
106-
throw new Error('something went wrong!!!')
107-
}
108-
return res.json()
109-
})
110-
})
11160

11261
const { mutate: deleteUpdate } = useMutation(
11362
() => {
@@ -143,19 +92,22 @@ export function HomePageFeedUpdate({
14392
}
14493
)
14594

146-
const [{ count: likesCount, hasLiked }, dispatch] = useReducer(
147-
reducer,
148-
initialState
149-
)
150-
151-
useEffect(() => {
152-
if (!isLoading && !isError) {
153-
dispatch({
154-
type: 'set',
155-
payload: { hasLiked: data.liked, count: update.likes.data },
156-
})
157-
}
158-
}, [data?.liked, isError, isLoading, update.likes.data])
95+
const { count: likesCount, hasLiked, toggleLike } = useLikes({
96+
initialCount: update.likes.data,
97+
query: {
98+
key: ['api/fauna/has-liked-update', update.id],
99+
endpoint: '/api/fauna/has-liked-update',
100+
body: {
101+
updateId: update.id,
102+
},
103+
},
104+
mutation: {
105+
endpoint: '/api/fauna/toggle-update-like',
106+
body: {
107+
updateId: update.id,
108+
},
109+
},
110+
})
159111

160112
return (
161113
<>
@@ -270,8 +222,7 @@ export function HomePageFeedUpdate({
270222
setIsLikeModalOpen(true)
271223
return
272224
}
273-
dispatch({ type: 'toggle' })
274-
mutate()
225+
toggleLike()
275226
}}
276227
>
277228
<ThumbsUp

src/components/useLikes.ts

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import { useEffect, useReducer } from 'react'
2+
import { useMutation, useQuery } from 'react-query'
3+
4+
type LikeData = {
5+
count: number
6+
hasLiked: boolean
7+
}
8+
const initialState: LikeData = { count: 0, hasLiked: false }
9+
10+
function reducer(state: LikeData, action: { type: string; payload?: any }) {
11+
switch (action.type) {
12+
case 'toggle':
13+
return {
14+
hasLiked: !state.hasLiked,
15+
count: state.hasLiked
16+
? Number(state.count) - 1
17+
: Number(state.count) + 1,
18+
}
19+
case 'set':
20+
return { count: action.payload.count, hasLiked: action.payload.hasLiked }
21+
default:
22+
throw new Error()
23+
}
24+
}
25+
26+
export function useLikes({
27+
initialCount,
28+
query,
29+
mutation,
30+
}: {
31+
initialCount: number
32+
query: {
33+
key: string | string[]
34+
endpoint: string
35+
body: any
36+
}
37+
mutation: {
38+
endpoint: string
39+
body: any
40+
}
41+
}) {
42+
const { isLoading, isError, data } = useQuery(query.key, () => {
43+
return fetch(query.endpoint, {
44+
method: 'POST',
45+
headers: {
46+
'Content-Type': 'application/json',
47+
},
48+
body: JSON.stringify(query.body),
49+
}).then((res) => res.json())
50+
})
51+
52+
const { mutate } = useMutation(() => {
53+
return fetch(mutation.endpoint, {
54+
method: 'POST',
55+
headers: {
56+
'Content-Type': 'application/json',
57+
},
58+
body: JSON.stringify(mutation.body),
59+
}).then((res) => {
60+
if (!res.ok) {
61+
throw new Error('something went wrong!!!')
62+
}
63+
return res.json()
64+
})
65+
})
66+
67+
const [{ count, hasLiked }, dispatch] = useReducer(reducer, initialState)
68+
69+
useEffect(() => {
70+
if (!isLoading && !isError) {
71+
dispatch({
72+
type: 'set',
73+
payload: { hasLiked: data.liked, count: initialCount },
74+
})
75+
}
76+
}, [data?.liked, initialCount, isError, isLoading])
77+
78+
const toggleLike = () => {
79+
dispatch({ type: 'toggle' })
80+
mutate()
81+
}
82+
83+
return {
84+
count,
85+
hasLiked,
86+
toggleLike,
87+
}
88+
}

0 commit comments

Comments
 (0)