Skip to content

Commit ba772a1

Browse files
committed
tweakss part 7
1 parent 0b6ceba commit ba772a1

5 files changed

Lines changed: 58 additions & 39 deletions

File tree

src/content/7/en/part7d.md

Lines changed: 58 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -7,33 +7,70 @@ lang: en
77

88
<div class="content">
99

10-
In addition to the eight exercises in the [React Hooks](/en/part7/more_about_react_hooks) sections of this part of the course material, 15 exercises continue our work on the BlogList application that we worked on in parts four and five of the course material. Some of the following exercises are "features" that are independent of one another, meaning that there is no need to finish them in any particular order. You are free to skip over a part of the exercises if you wish to do so. Quite many of them are about applying the advanced state management technique (Zustand, React Query and context) covered in [part 6](/en/part6).
10+
In addition to the six exercises in the [React Hooks](/en/part7/more_about_react_hooks) sections of this part of the course material, 16 exercises continue our work on the BlogList application that we worked on in parts four and five of the course material. Some of the following exercises are "features" that are independent of one another, meaning that there is no need to finish them in any particular order. You are free to skip over a part of the exercises if you wish to do so. Quite many of them are about applying the advanced state management technique (Zustand, React Query and context) covered in [part 6](/en/part6).
1111

1212
If you do not want to use your BlogList application, you are free to use the code from the model solution as a starting point for these exercises.
1313

1414
Many of the exercises in this part of the course material will require the [refactoring](https://en.wikipedia.org/wiki/Code_refactoring) of existing code. This is a common reality of extending existing applications, meaning that refactoring is an important and necessary skill even if it may feel difficult and unpleasant at times.
1515

1616
One good piece of advice for both refactoring and writing new code is to take <i>baby steps</i>. Losing your sanity is almost guaranteed if you leave the application in a completely broken state for long periods while refactoring.
1717

18+
**These exercises assume that you have already completed the exercises [5.24-5.29](/en/part5/react_router_ui_frameworks#exercises-5-24-5-29). If you have not, do those first.**
19+
1820
</div>
1921

2022
<div class="tasks">
2123

22-
### Exercises 7.7.-7.21.
24+
### Exercises 7.7.-7.22.
25+
26+
These exercises assume that you have already completed the exercises [5.24-5.29](/en/part5/react_router_ui_frameworks#exercises-5-24-5-29). If you have not, do those first.
2327

2428
#### 7.7: Frontend and backend in the same repository
2529

2630
During the course, the frontend and backend of the BlogList application have lived in separate repositories. A common real-world practice is to place both into a single repository, which simplifies deployment and makes it easier to share code between the two.
2731

2832
Read the section [Frontend and backend in the same repository](/en/part7/miscellaneous#frontend-and-backend-in-the-same-repository) from the course material and restructure your application accordingly. Place the frontend and backend source code in the same repository while keeping their <i>package.json</i> files separate.
2933

34+
Make sure that the development workflow still works: running <i>npm run dev</i> in the frontend directory should start the Vite dev server with hot reload as before. Also verify that the production build works: the backend should be able to serve the built frontend as a static site using a command such as <i>npm run build && npm start</i> (or equivalent scripts you define).
35+
36+
<i>Note:</i> if you run into strange dependency errors after reorganising the repository, the safest fix is often to delete all <i>node_modules</i> directories and run <i>npm install</i> again from scratch in each of the relevant directories.
37+
3038
#### 7.8: Error boundary
3139

32-
Errors in a React application that are not caught anywhere will result in a blank page. This is not a good user experience. Handle errors more gracefully by adding an [error boundary](https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary) to your application.
40+
Errors in a React application that are not caught anywhere will result in a blank page. This is not a good user experience. The standard React solution to this problem is the concept of an error boundary, that is a component that wraps part of the component tree and catches any rendering errors that occur within it, displaying a fallback UI instead of crashing the whole page.
41+
42+
Read the section [Error boundary](/en/part7/miscellaneous#error-boundary) from the course material. Then add an error boundary component to your application that catches any rendering errors and displays a user-friendly error message instead of a blank page.
43+
44+
The error boundary should be added to the app so that the navigation bar remains outside it. If a rendering error occurs anywhere in the rest of the application, the error boundary catches it and displays a user-friendly error message like this:
45+
46+
![](../../images/7/b1.png)
47+
48+
You can simulate a rendering error by temporarily throwing an exception inside one of your components, for example:
49+
50+
```js
51+
const BlogList = ({ blogs }) => {
52+
throw new Error('simulated error') /*/ highlight line
53+
return (
54+
// ...
55+
)
56+
}
57+
```
58+
59+
#### 7.9: Nonexisting routes
3360
34-
Read the section [Error boundary](/en/part7/miscellaneous#error-boundary) from the course material. Add an error boundary component that catches any rendering errors in the app and displays a user-friendly error message instead of a blank page.
61+
App has also another kind of error. If user tries to navigate to a non existing route such as
3562
36-
#### 7.9: Automatic Code Formatting
63+
![](../../images/7/b2.png)
64+
65+
or
66+
67+
![](../../images/7/b3.png)
68+
69+
the result is a blank page. Fix the routing so that navigating to a non-existing path shows a proper "Page not found" message instead. React Router's [splat route](https://reactrouter.com/start/framework/routing#splats) (<i>path="*"</i>) is the right tool for this: it matches any path that no other route covers. The result should look like this:
70+
71+
![](../../images/7/b4.png)
72+
73+
#### 7.10: Automatic Code Formatting
3774
3875
In the previous parts, we used ESLint to ensure that the code follows the defined conventions. [Prettier](https://prettier.io/) is yet another approach for the same. According to the documentation, Prettier is <i>an opinionated code formatter</i>, that is, Prettier not only controls the code style but also formats the code according to the definition.
3976
@@ -43,63 +80,63 @@ Take Prettier to use in your app and configure it to work with your editor.
4380
4481
### State Management: Zustand
4582
46-
<i>There are two alternative versions to choose for exercises 7.10-7.13: you can do the state management of the application either using Zustand or React Query and Context</i>. If you want to maximize your learning, you should do both versions!
83+
<i>There are two alternative versions to choose for exercises 7.11-7.14: you can do the state management of the application either using Zustand or React Query and Context</i>. If you want to maximize your learning, you should do both versions!
4784
4885
Note: if you completed part 6 using Redux, you can of course use Redux instead of Zustand in this exercise series!
4986
50-
#### 7.10: Zustand, Step 1
87+
#### 7.11: Zustand, Step 1
5188
5289
Refactor the application to use Zustand to manage the notification data.
5390
54-
#### 7.11: Zustand, Step 2
91+
#### 7.12: Zustand, Step 2
5592
5693
<i>Note</i> that this and the next two exercises are quite laborious but incredibly educational.
5794
5895
Store the information about blog posts in the Zustand store. In this exercise, it is enough that you can see the blogs in the backend and create a new blog.
5996
6097
You are free to manage the state for logging in and creating new blog posts by using the internal state of React components.
6198
62-
#### 7.12: Zustand, Step 3
99+
#### 7.13: Zustand, Step 3
63100
64101
Expand your solution so that it is again possible to like and delete a blog.
65102
66-
#### 7.13: Zustand, Step 4
103+
#### 7.14: Zustand, Step 4
67104
68105
Store the information about the signed-in user in the Zustand store.
69106
70107
### State Management: React Query and Context
71108
72-
<i>There are two alternative versions to choose for exercises 7.10-7.13: you can do the state management of the application either using Zustand or React Query and Context</i>. If you want to maximize your learning, you should do both versions!
109+
<i>There are two alternative versions to choose for exercises 7.11-7.14: you can do the state management of the application either using Zustand or React Query and Context</i>. If you want to maximize your learning, you should do both versions!
73110
74-
#### 7.10: React Query and Context step 1
111+
#### 7.11: React Query and Context step 1
75112
76113
Refactor the app to use the useReducer-hook and context to manage the notification data.
77114
78-
#### 7.11: React Query and Context step 2
115+
#### 7.12: React Query and Context step 2
79116
80117
Use React Query to manage the state for blog posts. For this exercise, it is sufficient that the application displays existing blogs and that the creation of a new blog is successful.
81118
82119
You are free to manage the state for logging in and creating new blog posts by using the internal state of React components.
83120
84-
#### 7.12: React Query and Context step 3
121+
#### 7.13: React Query and Context step 3
85122
86123
Expand your solution so that it is again possible to like and delete a blog.
87124
88-
#### 7.13: React Query and Context step 4
125+
#### 7.14: React Query and Context step 4
89126
90127
Use the useReducer-hook and context to manage the data for the logged in user.
91128
92129
### Views
93130
94131
The rest of the tasks are common to both the Zustand and React Query versions.
95132
96-
#### 7.14: Users view
133+
#### 7.15: Users view
97134
98135
Implement a view to the application that displays all of the basic information related to users:
99136
100137
![browser blogs with users table showing blogs created](../../images/7/41.png)
101138
102-
#### 7.15: Individual User View
139+
#### 7.16: Individual User View
103140
104141
Implement a view for individual users that displays all of the blog posts added by that user:
105142
@@ -134,25 +171,7 @@ const User = () => {
134171
}
135172
```
136173
137-
#### 7.16: Blog View
138-
139-
Implement a separate view for blog posts. You can model the layout of your view after the following example:
140-
141-
![browser blogs showing single blog via URL /blogs/number](../../images/7/45.png)
142-
143-
Users should be able to access this view by clicking the name of the blog post in the view that lists all of the blog posts.
144-
145-
![browser showing blogs are clickable](../../images/7/46.png)
146-
147-
After you're done with this exercise, the functionality that was implemented in exercise 5.7 is no longer necessary. Clicking a blog post no longer needs to expand the item in the list and display the details of the blog post.
148-
149-
#### 7.17: Navigation
150-
151-
Implement a navigation menu for the application:
152-
153-
![browser blogs navigation navigation menu](../../images/7/47.png)
154-
155-
#### 7.18: Comments, step 1
174+
#### 7.19: Comments, step 1
156175
157176
Implement the functionality for commenting the blog posts:
158177
@@ -164,17 +183,17 @@ In this exercise, it is enough for the frontend to only display the comments tha
164183
165184
An appropriate mechanism for adding comments to a blog post would be an HTTP POST request to the <i>api/blogs/:id/comments</i> endpoint.
166185
167-
#### 7.19: Comments, step 2
186+
#### 7.20: Comments, step 2
168187
169188
Extend your application so that users can add comments to blog posts from the frontend:
170189
171190
![browser showing comments added via frontend](../../images/7/49.png)
172191
173-
#### 7.20: Styles, step 1
192+
#### 7.21: Styles, step 1
174193
175194
Improve the appearance of your application by applying one of the methods shown in the course material.
176195
177-
#### 7.21: Styles, step 2
196+
#### 7.22: Styles, step 2
178197
179198
You can mark this exercise as finished if you use an hour or more for styling your application.
180199

src/content/images/7/b1.png

45 KB
Loading

src/content/images/7/b2.png

31.7 KB
Loading

src/content/images/7/b3.png

29.5 KB
Loading

src/content/images/7/b4.png

35.7 KB
Loading

0 commit comments

Comments
 (0)