Skip to content

Commit 96a9826

Browse files
removed postsArray state from component, not relying on React Query for state
1 parent 65a1230 commit 96a9826

File tree

6 files changed

+150
-88
lines changed

6 files changed

+150
-88
lines changed

examples/example-2/client/src/client/App.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import React from 'react';
22
import PostsOne from './components/PostsOne';
33

44
const App = () => {
5+
// const [screenView, setScreenView] = useState<string>('Posts One');
6+
57
return (
68
<>
79
<div className="window">

examples/example-2/client/src/client/components/PostsOne.tsx

Lines changed: 99 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,12 @@
1-
import React from 'react';
2-
3-
import { useState, FormEvent } from 'react';
1+
import React, { FormEvent } from 'react';
42
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
5-
63
import { usePostInputChange } from '../hooks/usePostInputChange';
74
import { useCommentInputChange } from '../hooks/useCommentInputChange';
85
import { Post, CreateCommentParams } from '../types';
9-
import { openComment } from '../functions/openComment';
106

117
function PostsOne() {
128
const queryClient = useQueryClient();
139

14-
const [postsArray, setPostsArray] = useState<Post[]>([]);
1510
const { postInput, setPostInput, postInputChange } = usePostInputChange();
1611
const { commentInputs, setCommentInputs, commentInputChange } =
1712
useCommentInputChange();
@@ -25,7 +20,6 @@ function PostsOne() {
2520
}
2621

2722
const newPostsArray = await response.json();
28-
setPostsArray(newPostsArray);
2923

3024
return newPostsArray;
3125
} catch (error) {
@@ -35,16 +29,14 @@ function PostsOne() {
3529

3630
// query for fetching old posts
3731
const {
38-
data: postsState,
32+
data: postsArray,
3933
isLoading,
4034
error,
41-
} = useQuery({
35+
} = useQuery<Post[]>({
4236
queryKey: ['posts'],
4337
queryFn: fetchPostsRoute,
4438
});
4539

46-
console.log(postsState, isLoading);
47-
4840
// create-post route
4941
const createPostRoute = async (newPost: Post) => {
5042
try {
@@ -70,9 +62,8 @@ function PostsOne() {
7062
// mutation for creating a new post
7163
const newPostMutation = useMutation({
7264
mutationFn: createPostRoute,
73-
onSuccess: updatedPostsArray => {
65+
onSuccess: () => {
7466
queryClient.invalidateQueries({ queryKey: ['posts'] });
75-
setPostsArray(updatedPostsArray);
7667
},
7768
});
7869

@@ -118,9 +109,8 @@ function PostsOne() {
118109
// mutation for liking a post
119110
const likePostMutation = useMutation({
120111
mutationFn: likePostRoute,
121-
onSuccess: updatedPostsArray => {
112+
onSuccess: () => {
122113
queryClient.invalidateQueries({ queryKey: ['posts'] });
123-
setPostsArray(updatedPostsArray);
124114
},
125115
});
126116

@@ -154,9 +144,8 @@ function PostsOne() {
154144
// mutation for deleting a post
155145
const deletePostMutation = useMutation({
156146
mutationFn: deletePostRoute,
157-
onSuccess: updatedPostsArray => {
147+
onSuccess: () => {
158148
queryClient.invalidateQueries({ queryKey: ['posts'] });
159-
setPostsArray(updatedPostsArray);
160149
},
161150
});
162151

@@ -193,9 +182,8 @@ function PostsOne() {
193182
// mutation for creating a comment
194183
const createCommentMutation = useMutation({
195184
mutationFn: createCommentRoute,
196-
onSuccess: updatedPostsArray => {
185+
onSuccess: () => {
197186
queryClient.invalidateQueries({ queryKey: ['posts'] });
198-
setPostsArray(updatedPostsArray);
199187
},
200188
});
201189

@@ -214,6 +202,41 @@ function PostsOne() {
214202
}
215203
};
216204

205+
// open-comment route
206+
const openCommentRoute = async (index: number) => {
207+
try {
208+
const response = await fetch('http://localhost:3000/open-comment', {
209+
method: 'POST',
210+
headers: {
211+
'Content-Type': 'application/json',
212+
},
213+
body: JSON.stringify({ index: index }),
214+
});
215+
216+
if (!response.ok) {
217+
throw new Error('Error creating post');
218+
}
219+
220+
const updatedPostsArray = await response.json();
221+
return updatedPostsArray;
222+
} catch (errror) {
223+
console.error('Creating post failed:', error);
224+
}
225+
};
226+
227+
// mutation for opening comment
228+
const openCommentMutation = useMutation({
229+
mutationFn: openCommentRoute,
230+
onSuccess: () => {
231+
queryClient.invalidateQueries({ queryKey: ['posts'] });
232+
},
233+
});
234+
235+
// function that opens comment
236+
const openComment = (index: number) => {
237+
openCommentMutation.mutate(index);
238+
};
239+
217240
return (
218241
<>
219242
<div className="posts-container">
@@ -228,60 +251,64 @@ function PostsOne() {
228251
Send
229252
</button>
230253
</form>
231-
{postsArray.map((post, index) => (
232-
<div
233-
className={`post-container ${index % 2 === 0 ? 'green' : 'blue'}`}
234-
key={index}
235-
>
236-
<div className="post-text">{post.text}</div>
237-
<div className="like-comment-container">
238-
<button
239-
className={`button ${post.liked === true ? 'red' : ''}`}
240-
onClick={() => likePost(index)}
241-
>
242-
Like
243-
</button>
244-
<button
245-
className="button left-margin"
246-
onClick={() => openComment(postsArray, index, setPostsArray)}
247-
>
248-
Comment
249-
</button>
250-
<button
251-
className="button left-margin"
252-
onClick={() => deletePost(index)}
253-
>
254-
Delete
255-
</button>
256-
</div>
257-
<div className="comment-section">
258-
{post.createComment === true && (
259-
<>
260-
{' '}
261-
<form
262-
className="create-post-container-2"
263-
onSubmit={event => createComment(event, index)}
264-
>
265-
<input
266-
type="text"
267-
className="input-2"
268-
value={commentInputs[index] || ''}
269-
onChange={event => commentInputChange(index, event)}
270-
/>
271-
<button className="button margin-left" type="submit">
272-
Send
273-
</button>
274-
</form>
275-
{post.comments.map((comment, commentIndex) => (
276-
<div className="post-text" key={commentIndex}>
277-
{`${commentIndex}) ${comment}`}
278-
</div>
279-
))}
280-
</>
281-
)}
254+
255+
{isLoading && <div>Loading...</div>}
256+
{error && <div>Error loading posts</div>}
257+
{postsArray &&
258+
postsArray.map((post, index) => (
259+
<div
260+
className={`post-container ${index % 2 === 0 ? 'green' : 'blue'}`}
261+
key={index}
262+
>
263+
<div className="post-text">{post.text}</div>
264+
<div className="like-comment-container">
265+
<button
266+
className={`button ${post.liked === true ? 'red' : ''}`}
267+
onClick={() => likePost(index)}
268+
>
269+
Like
270+
</button>
271+
<button
272+
className="button left-margin"
273+
onClick={() => openComment(index)}
274+
>
275+
Comment
276+
</button>
277+
<button
278+
className="button left-margin"
279+
onClick={() => deletePost(index)}
280+
>
281+
Delete
282+
</button>
283+
</div>
284+
<div className="comment-section">
285+
{post.createComment === true && (
286+
<>
287+
{' '}
288+
<form
289+
className="create-post-container-2"
290+
onSubmit={event => createComment(event, index)}
291+
>
292+
<input
293+
type="text"
294+
className="input-2"
295+
value={commentInputs[index] || ''}
296+
onChange={event => commentInputChange(index, event)}
297+
/>
298+
<button className="button margin-left" type="submit">
299+
Send
300+
</button>
301+
</form>
302+
{post.comments.map((comment, commentIndex) => (
303+
<div className="post-text" key={commentIndex}>
304+
{`${commentIndex}) ${comment}`}
305+
</div>
306+
))}
307+
</>
308+
)}
309+
</div>
282310
</div>
283-
</div>
284-
))}
311+
))}
285312
</div>
286313
</>
287314
);
Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,44 @@
11
import React, { useEffect } from 'react';
22
import { useQueryClient } from '@tanstack/react-query';
33

4-
export type SubscribeEvent = {
5-
// structure of subscribe event
4+
type SubscribeEvent = {
5+
type: string;
6+
query: {
7+
state: {
8+
data: any;
9+
};
10+
};
11+
};
12+
13+
const cleanData = (event: SubscribeEvent) => {
14+
const relevantTypes = ['added', 'removed', 'updated'];
15+
const eventType = event.type;
16+
17+
if (!relevantTypes.includes(eventType)) return;
18+
19+
console.log(event);
20+
21+
// if (event.type === 'added') {
22+
// console.log('ADDED', event.query.state.data);
23+
// }
24+
25+
// if (event.type === 'updated') {
26+
// console.log('UPDATED', event.query.state.data);
27+
// }
628
};
729

830
const ReactQueryRewind = () => {
9-
// React does not allow hooks inside of useEffect
1031
const queryClient = useQueryClient();
32+
1133
useEffect(() => {
1234
const queryCache = queryClient.getQueryCache();
13-
// tbh this is a callback - it will only every take in one event. You can't accidentally call this function. It looks like there are ways to do partial checks in enormous objects but it might not be worth it for us. We can type check the fields we care about and send those along to the pure functions
35+
1436
const unsubscribe = queryCache.subscribe((event: SubscribeEvent) => {
15-
// setTimeout ensure it runs after components load
16-
setTimeout(() => {
17-
// These need to be optimized so that if it's data I don't want, the functions are never called or return as early as possible
18-
console.log(event);
19-
// logging(event);
20-
}, 0);
37+
cleanData(event);
2138
});
2239

2340
return () => unsubscribe();
2441
}, []);
25-
// useEffect(() => console.log('Effect in pacakge'), [])
26-
console.log('React Query Rewind Test');
2742
return <></>;
2843
};
2944

@@ -37,6 +52,5 @@ export const RewindHook = () => {
3752
// return () => unsubscribe();
3853
// }, [])
3954

40-
console.log('Hook Test');
4155
return;
4256
};

examples/example-2/server/database.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
{
44
"id": 1,
55
"text": "First Post",
6-
"liked": false,
6+
"liked": true,
77
"comments": [
88
"First comment on first post",
99
"Second comment on first post"

examples/example-2/server/server.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,26 @@ app.post('/create-comment', async (req, res) => {
107107
const postIndex = parseInt(index, 10);
108108

109109
db.posts[postIndex].comments.push(comment);
110-
// db.posts[postIndex].createComment = true;
110+
111+
await fs.writeFile(dbPath, JSON.stringify(db, null, 2), 'utf8');
112+
113+
res.status(201).json(db.posts);
114+
} catch (err) {
115+
console.error('Error updating database.json:', err);
116+
res.status(500).send('Error saving data');
117+
}
118+
});
119+
120+
// open comment
121+
app.post('/open-comment', async (req, res) => {
122+
try {
123+
const dbPath = path.join(__dirname, 'database.json');
124+
const data = await fs.readFile(dbPath, 'utf8');
125+
const db = JSON.parse(data);
126+
127+
const index = parseInt(req.body.index, 10);
128+
129+
db.posts[index].createComment = !db.posts[index].createComment;
111130

112131
await fs.writeFile(dbPath, JSON.stringify(db, null, 2), 'utf8');
113132

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"watch": "rollup -c -w",
2020
"prepublishOnly": "npm run build",
2121
"clean": "rm -rf dist",
22-
"install-all": "npm install && (cd examples/example-1 && npm install) && (cd examples/example-2 && npm install)",
22+
"install-all": "npm install && (cd examples/example-1 && npm install) && (cd examples/example-2 && npm install) && (cd examples/example-2/client && npm install) && (cd examples/example-2/server && npm install)",
2323
"link-package": "npm link && (cd examples/example-1 && npm link react-query-rewind)",
2424
"link-dependencies": "npm link examples/example-1/node_modules/react examples/example-1/node_modules/react-dom examples/example-1/node_modules/@tanstack/react-query",
2525
"unlink-package": "(cd examples/example-1 && npm unlink react-query-rewind) && npm unlink"

0 commit comments

Comments
 (0)