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: pages/tutorials/React.md
+19-16Lines changed: 19 additions & 16 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -189,6 +189,18 @@ ReactDOM.render(
189
189
);
190
190
```
191
191
192
+
## Type assertions
193
+
194
+
One final thing we'll point out in this section is the line `document.getElementById('root') as HTMLElement`.
195
+
This syntax is called a *type assertion*, sometimes also called a *cast*.
196
+
This is a useful way of telling TypeScript that you know a little more about the type than the type checker does.
197
+
198
+
The reason we need to do so in this case is that `getElementById`'s return type is `HTMLElement | null`, meaning that it can return `null`.
199
+
We're operating under the assumption that `getElementById` will actually succeed, so we need convince TypeScript of that using the `as` syntax.
200
+
201
+
TypeScript also has a trailing "bang" syntax (`!`), which removes `null` and `undefined` from the prior expression.
202
+
So we *could* have written `document.getElementById('root')!`, but in this case we wanted to be a bit more explicit.
203
+
192
204
# Adding style 😎
193
205
194
206
Styling a component with our setup is easy.
@@ -218,7 +230,7 @@ So in `src/components/Hello.tsx`, we'll add the following import.
218
230
import'./Hello.css';
219
231
```
220
232
221
-
# Writing tests
233
+
# Writing tests with Jest
222
234
223
235
We had a certain set of assumptions about our `Hello` component.
224
236
Let's reiterate what they were:
@@ -367,7 +379,7 @@ export type DECREMENT_ENTHUSIASM = typeof DECREMENT_ENTHUSIASM;
367
379
368
380
This `const`/`type` pattern allows us to use TypeScript's string literal types in an easily accessible & refactorable way.
369
381
370
-
Next, we'll create a set of actions and functions that can quickly create these actions in `src/actions/index.tsx`.
382
+
Next, we'll create a set of actions and functions that can create these actions in `src/actions/index.tsx`.
371
383
372
384
```ts
373
385
import*asconstantsfrom'../constants'
@@ -397,14 +409,15 @@ export function decrementEnthusiasm(): DecrementEnthusiasm {
397
409
398
410
We've created two types that describe what increment actions and decrement actions should look like.
399
411
We also created a type (`EnthusiasmAction`) to describe cases where an action could be an increment or a decrement.
400
-
Finally, we made two functions that actually manufacture the actions.
412
+
Finally, we made two functions that actually manufacture the actions which we can use instead of writing out bulky object literals.
401
413
402
414
There's clearly boilerplate here, so you should feel free to look into libraries like [redux-actions](https://www.npmjs.com/package/redux-actions) once you've got the hang of things.
403
415
404
416
## Adding a reducer
405
417
406
418
We're ready to write our first reducer!
407
419
Reducers are just functions that generate changes by creating modified copies of our application's state, but that have *no side effects*.
420
+
In other words, they're what we call *[pure functions](https://en.wikipedia.org/wiki/Pure_function)*.
408
421
409
422
Our reducer will go under `src/reducers/index.tsx`.
410
423
Its function will be to ensure that increments raise the enthusiasm level by 1, and that decrements reduce the enthusiasm level by 1, but that the level never falls below 1.
@@ -438,9 +451,11 @@ Consider looking into Jest's [toEqual](https://facebook.github.io/jest/docs/expe
438
451
## Making a container
439
452
440
453
When writing with Redux, we will often write components as well as containers.
454
+
Components are often data-agnostic, and work mostly at a presentational level.
441
455
*Containers* typically wrap components and feed them any data that is necessary to display and modify state.
456
+
You can read more about this concept on [Dan Abramov's article *Presentational and Container Components*](https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0).
442
457
443
-
First let's update `src/components/Hello.tsx` so that it will have a means of modifying state.
458
+
First let's update `src/components/Hello.tsx` so that it can modify state.
444
459
We'll add two optional callback properties to `Props` named `onIncrement` and `onDecrement`:
445
460
446
461
```ts
@@ -595,18 +610,6 @@ ReactDOM.render(
595
610
596
611
Notice that `Hello` no longer needs props, since we used our `connect` function to adapt our application's state for our wrapped `Hello` component's props.
597
612
598
-
### Type assertions
599
-
600
-
One final thing we'll point out in this section is the line `document.getElementById('root') as HTMLElement`.
601
-
This syntax is called a *type assertion*, often also just called a *cast*.
602
-
This is a useful way of telling TypeScript that you know a little more about the type than the type checker does.
603
-
604
-
The reason we need to do so in this case is that `getElementById`'s return type is `HTMLElement | null`, meaning that it can return `null`.
605
-
We're operating under the assumption that `getElementById` will actually succeed, so we need convince TypeScript of that using the `as` syntax.
606
-
607
-
TypeScript also has a trailing "bang" (`!`) syntax, which removes `null` and `undefined` from the prior expression.
608
-
So we *could* have written `document.getElementById('root')!`, but in this case we wanted to be a bit more explicit.
609
-
610
613
# Ejecting
611
614
612
615
If at any point, you feel like there are certain customizations that the create-react-app setup has made difficult, you can always opt-out and get the various configuration options you need.
0 commit comments