You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/content/7/en/part7b.md
+6-6Lines changed: 6 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -15,11 +15,11 @@ This part also contains a [series of exercises](/en/part7/exercises_extending_th
15
15
16
16
React offers 15 different [built-in hooks](https://reactjs.org/docs/hooks-reference.html), of which the most popular ones are the [useState](https://reactjs.org/docs/hooks-reference.html#usestate) and [useEffect](https://reactjs.org/docs/hooks-reference.html#useeffect) hooks that we have already been using extensively.
17
17
18
-
In [part 5](/en/part5/props_children_and_proptypes#references-to-components-with-ref) we used the [useImperativeHandle](https://reactjs.org/docs/hooks-reference.html#useimperativehandle) hook which allows components to provide their functions to other components.
18
+
In [part 5](/en/part5/props_children_and_proptypes#references-to-components-with-ref) we used the [useImperativeHandle](https://reactjs.org/docs/hooks-reference.html#useimperativehandle) hook which allows components to provide their functions to other components. In [part 6](/en/part6/react_query_use_reducer_and_the_contex) we used [useReducer](https://reactjs.org/docs/hooks-reference.html#usereducer) and [useContext](https://reactjs.org/docs/hooks-reference.html#usecontext) to implement a Redux like state management.
19
19
20
-
Within the last couple of years, many React libraries have begun to offer hook-based APIs. [In part 6](/en/part6/flux_architecture_and_redux) we used the [useSelector](https://react-redux.js.org/api/hooks#useselector) and [useDispatch](https://react-redux.js.org/api/hooks#usedispatch) hooks from the react-redux library to share our redux-store and dispatch function to our components. Redux's hook-based API is a lot easier to use than the older, still available, [connect](/en/part6/connect) API.
20
+
Within the last couple of years, many React libraries have begun to offer hook-based APIs. [In part 6](/en/part6/flux_architecture_and_redux) we used the [useSelector](https://react-redux.js.org/api/hooks#useselector) and [useDispatch](https://react-redux.js.org/api/hooks#usedispatch) hooks from the react-redux library to share our redux-store and dispatch function to our components.
21
21
22
-
The [React Router's](https://reactrouter.com/en/main/start/tutorial) API we introduced in the [previous part](/en/part7/react_router) is also partially [hook](https://reacttraining.com/react-router/web/api/Hooks)-based. Its hooks can be used to access URL parameters and the _navigation_ object, which allows for manipulating the browser URL programmatically.
22
+
The [React Router's](https://reactrouter.com/en/main/start/tutorial) API we introduced in the [previous part](/en/part7/react_router) is also partially [hook](https://reacttraining.com/react-router/web/api/Hooks)-based. Its hooks can be used to access URL parameters and the <i>navigation</i> object, which allows for manipulating the browser URL programmatically.
23
23
24
24
As mentioned in [part 1](/en/part1/a_more_complex_state_debugging_react_apps#rules-of-hooks), hooks are not normal functions, and when using those we have to adhere to certain [rules or limitations](https://reactjs.org/docs/hooks-rules.html). Let's recap the rules of using hooks, copied verbatim from the official React documentation:
25
25
@@ -50,7 +50,7 @@ We implemented a counter application in [part 1](/en/part1/component_state_event
50
50
51
51
```js
52
52
import { useState } from'react'
53
-
constApp= (props) => {
53
+
constApp= () => {
54
54
const [counter, setCounter] =useState(0)
55
55
56
56
return (
@@ -103,7 +103,7 @@ Our custom hook uses the _useState_ hook internally to create its state. The hoo
103
103
React components can use the hook as shown below:
104
104
105
105
```js
106
-
constApp= (props) => {
106
+
constApp= () => {
107
107
constcounter=useCounter()
108
108
109
109
return (
@@ -426,7 +426,7 @@ The application is otherwise complete, but in this exercise, you have to impleme
426
426
427
427
Use the API endpoint [full name](https://restcountries.com/#api-endpoints-v3-full-name) to fetch a country's details in a _useEffect_ hook within your custom hook.
428
428
429
-
Note that in this exercise it is essential to use useEffect's [second parameter](https://reactjs.org/docs/hooks-reference.html#conditionally-firing-an-effect) array to control when the effect function is executed.
429
+
Note that in this exercise it is essential to use useEffect's [second parameter](https://reactjs.org/docs/hooks-reference.html#conditionally-firing-an-effect) array to control when the effect function is executed. See the course [part 2](/en/part2/adding_styles_to_react_app#couple-of-important-remarks) for more info how the second parameter could be used.
Copy file name to clipboardExpand all lines: src/content/7/en/part7c.md
+11-17Lines changed: 11 additions & 17 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -31,15 +31,15 @@ Let's install the package with the command:
31
31
npm install react-bootstrap
32
32
```
33
33
34
-
Then let's add a link for loading the CSS stylesheet for Bootstrap inside of the <i>head</i> tag in the <i>public/index.html</i> file of the application:
34
+
Then let's add a [link for loading the CSS stylesheet](https://react-bootstrap.github.io/getting-started/introduction#stylesheets) for Bootstrap inside of the <i>head</i> tag in the <i>public/index.html</i> file of the application:
@@ -66,6 +66,8 @@ We notice that this already affected the appearance of the application. The cont
66
66
67
67

68
68
69
+
#### Table
70
+
69
71
Next, let's make some changes to the <i>Notes</i> component so that it renders the list of notes as a [table](https://getbootstrap.com/docs/4.1/content/tables/). React Bootstrap provides a built-in [Table](https://react-bootstrap.github.io/components/table/) component for this purpose, so there is no need to define CSS classes separately.
70
72
71
73
```js
@@ -131,7 +133,8 @@ let Login = (props) => {
131
133
</Form.Group>
132
134
</Form>
133
135
</div>
134
-
)}
136
+
)
137
+
}
135
138
```
136
139
137
140
The number of components we need to import increases:
@@ -247,16 +250,7 @@ Install the library with the command
Now let's use MaterialUI to do the same modifications to the code we did earlier with bootstrap.
253
+
Now let's use MaterialUI to do the same modifications to the code we did earlier with Bootstrap.
260
254
261
255
Render the contents of the whole application within a [Container](https://mui.com/components/container/):
262
256
@@ -273,6 +267,8 @@ const App = () => {
273
267
}
274
268
```
275
269
270
+
#### Table
271
+
276
272
Let's start with the <i>Notes</i> component. We'll render the list of notes as a [table](https://mui.com/material-ui/react-table/#simple-table):
277
273
278
274
```js
@@ -504,7 +500,6 @@ Here are some other UI frameworks for your consideration. If you do not see your
504
500
-<https://semantic-ui.com/>
505
501
-<https://mantine.dev/>
506
502
-<https://react.fluentui.dev/>
507
-
-<https://storybook.js.org>
508
503
-<https://www.primefaces.org/primereact/>
509
504
-<https://v2.grommet.io>
510
505
-<https://blueprintjs.com>
@@ -514,7 +509,6 @@ Here are some other UI frameworks for your consideration. If you do not see your
514
509
-<https://master.co/>
515
510
-<https://nextui.org/>
516
511
517
-
518
512
### Styled components
519
513
520
514
There are also [other ways](https://blog.bitsrc.io/5-ways-to-style-react-components-in-2019-30f1ccc2b5b) of styling React applications that we have not yet taken a look at.
Copy file name to clipboardExpand all lines: src/content/7/en/part7d.md
+64-46Lines changed: 64 additions & 46 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -99,16 +99,36 @@ We define the functionality of webpack in the <i>webpack.config.js</i> file, whi
99
99
```js
100
100
constpath=require('path')
101
101
102
+
constconfig= () => {
103
+
return {
104
+
entry:'./src/index.js',
105
+
output: {
106
+
path:path.resolve(__dirname, 'build'),
107
+
filename:'main.js'
108
+
}
109
+
}
110
+
}
111
+
112
+
module.exports= config
113
+
```
114
+
115
+
**Note:** it would be possible to make the definition directly as an object instead of a function:
116
+
117
+
```js
118
+
constpath=require('path')
119
+
102
120
constconfig= {
103
121
entry:'./src/index.js',
104
122
output: {
105
123
path:path.resolve(__dirname, 'build'),
106
124
filename:'main.js'
107
125
}
108
126
}
127
+
109
128
module.exports= config
110
129
```
111
130
131
+
An object will suffice in many situations, but we will later need certain features that require the definition to be done as a function.
112
132
113
133
We will then define a new npm script called <i>build</i> that will execute the bundling with webpack:
114
134
@@ -176,18 +196,20 @@ Let's take a closer look at the contents of our current <i>webpack.config.js</i>
176
196
```js
177
197
constpath=require('path')
178
198
179
-
constconfig= {
180
-
entry:'./src/index.js',
181
-
output: {
182
-
path:path.resolve(__dirname, 'build'),
183
-
filename:'main.js'
199
+
constconfig= () => {
200
+
return {
201
+
entry:'./src/index.js',
202
+
output: {
203
+
path:path.resolve(__dirname, 'build'),
204
+
filename:'main.js'
205
+
}
184
206
}
185
207
}
186
208
187
209
module.exports= config
188
210
```
189
211
190
-
The configuration file has been written in JavaScript and the configuration object is exported using Node's module syntax.
212
+
The configuration file has been written in JavaScript and the function returning the configuration object is exported using Node's module syntax.
191
213
192
214
Our minimal configuration definition almost explains itself. The [entry](https://webpack.js.org/concepts/#entry) property of the configuration object specifies the file that will serve as the entry point for bundling the application.
193
215
@@ -268,26 +290,32 @@ We can use [loaders](https://webpack.js.org/concepts/loaders/) to inform webpack
268
290
Let's configure a loader to our application that transforms the JSX code into regular JavaScript:
269
291
270
292
```js
271
-
constconfig= {
272
-
entry:'./src/index.js',
273
-
output: {
274
-
path:path.resolve(__dirname, 'build'),
275
-
filename:'main.js',
276
-
},
277
-
// highlight-start
278
-
module: {
279
-
rules: [
280
-
{
281
-
test:/\.js$/,
282
-
loader:'babel-loader',
283
-
options: {
284
-
presets: ['@babel/preset-react'],
293
+
constpath=require('path')
294
+
295
+
constconfig= () => {
296
+
return {
297
+
entry:'./src/index.js',
298
+
output: {
299
+
path:path.resolve(__dirname, 'build'),
300
+
filename:'main.js'
301
+
},
302
+
// highlight-start
303
+
module: {
304
+
rules: [
305
+
{
306
+
test:/\.js$/,
307
+
loader:'babel-loader',
308
+
options: {
309
+
presets: ['@babel/preset-react'],
310
+
},
285
311
},
286
-
},
287
-
],
288
-
},
289
-
// highlight-end
312
+
],
313
+
},
314
+
// highlight-end
315
+
}
290
316
}
317
+
318
+
module.exports= config
291
319
```
292
320
293
321
Loaders are defined under the <i>module</i> property in the <i>rules</i> array.
@@ -625,7 +653,7 @@ const App = () => {
625
653
626
654
### Minifying the code
627
655
628
-
When we deploy the application to production, we are using the <i>main.js</i> code bundle that is generated by webpack. The size of the <i>main.js</i> file is 1356668 bytes even though our application only contains a few lines of our code. The large file size is because the bundle also contains the source code for the entire React library. The size of the bundled code matters since the browser has to load the code when the application is first used. With high-speed internet connections, 1356668 bytes is not an issue, but if we were to keep adding more external dependencies, loading speeds could become an issue, particularly for mobile users.
656
+
When we deploy the application to production, we are using the <i>main.js</i> code bundle that is generated by webpack. The size of the <i>main.js</i> file is 1009487 bytes even though our application only contains a few lines of our code. The large file size is because the bundle also contains the source code for the entire React library. The size of the bundled code matters since the browser has to load the code when the application is first used. With high-speed internet connections, 1009487 bytes is not an issue, but if we were to keep adding more external dependencies, loading speeds could become an issue, particularly for mobile users.
629
657
630
658
If we inspect the contents of the bundle file, we notice that it could be greatly optimized in terms of file size by removing all of the comments. There's no point in manually optimizing these files, as there are many existing tools for the job.
631
659
@@ -691,7 +719,7 @@ Let's store the following content in the <i>db.json</i> file:
691
719
692
720
Our goal is to configure the application with webpack in such a way that, when used locally, the application uses the json-server available in port 3001 as its backend.
693
721
694
-
The bundled file will then be configured to use the backend available at the <https://obscure-harbor-49797.herokuapp.com/api/notes> URL.
722
+
The bundled file will then be configured to use the backend available at the <https://notes2023.fly.dev/api/notes> URL.
695
723
696
724
We will install <i>axios</i>, start the json-server, and then make the necessary changes to the application. For the sake of changing things up, we will fetch the notes from the backend with our [custom hook](/en/part7/custom_hooks) called _useNotes_:
The address of the backend server is currently hardcoded in the application code. How can we change the address in a controlled fashion to point to the production backend server when the code is bundled for production?
740
768
741
-
Let's change the configuration object in the <i>webpack.config.js</i> file to a function instead of an object:
769
+
Webpack's configuration function has two parameters, <i>env</i> and <i>argv</i>. We can use the latter to find out the <i>mode</i> defined in the npm script:
742
770
743
771
```js
744
-
constpath=require('path');
772
+
constpath=require('path')
745
773
746
-
constconfig= (env, argv) => {
774
+
constconfig= (env, argv) => { // highlight-line
775
+
console.log('argv.mode:', argv.mode)
747
776
return {
748
-
entry:'./src/index.js',
749
-
output: {
750
-
// ...
751
-
},
752
-
devServer: {
753
-
// ...
754
-
},
755
-
devtool:'source-map',
756
-
module: {
757
-
// ...
758
-
},
759
-
plugins: [
760
-
// ...
761
-
],
777
+
// ...
762
778
}
763
779
}
764
780
765
781
module.exports= config
766
782
```
767
783
768
-
The definition remains almost the same, except for the fact that the configuration object is now returned by the function. The function receives the two parameters, <i>env</i> and <i>argv</i>, the second of which can be used for accessing the <i>mode</i> that is defined in the npm script.
784
+
Now, if we want, we can set Webpack to work differently depending on whether the application's operating environment, or <i>mode</i>, is set to production or development.
769
785
770
786
We can also use webpack's [DefinePlugin](https://webpack.js.org/plugins/define-plugin/) for defining <i>global default constants</i> that can be used in the bundled code. Let's define a new global constant <i>BACKEND\_URL</i> that gets a different value depending on the environment that the code is being bundled for:
If the configuration for development and production differs a lot, it may be a good idea to [separate the configuration](https://webpack.js.org/guides/production/) of the two into their own files.
833
849
850
+
Now, if the application is started with the command _npm start_ in development mode, it fetches the notes from the address http://localhost:3001/notes. The version bundled with the command _npm run build_ uses the address https://notes2023.fly.dev/api/notes to get the list of notes.
851
+
834
852
We can inspect the bundled production version of the application locally by executing the following command in the <i>build</i> directory:
0 commit comments