Skip to content

Commit f350429

Browse files
author
Jakub Kohoutek
committed
Exercise for live coding prepared, README for lecture improved, package-locks excluded from .gitignore
1 parent 4b2a1c9 commit f350429

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

82 files changed

+131220
-69
lines changed

.gitignore

-3
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,3 @@ typings/
6767
# mac file system
6868
.DS_Store
6969

70-
# ignore lock files to avoid endorsing vulnerable packages (recommend `npm audit` in README)
71-
package-lock.json
72-
yarn.lock

00-props-state/search-example/package-lock.json

+14,875
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

01-react-hooks/hooks-example/package-lock.json

+15,041
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

01-react-hooks/hooks-example/yarn.lock

+8,660
Large diffs are not rendered by default.

04-suspense-and-async-mode/README.md

+46-39
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,13 @@
22

33
## Code Splitting
44

5-
* Bundling your application is great, but as your app grows, your bundle size will grow too, especially if you are including large 3rd party libraries
6-
* This may have a huge impact on the time to first load and UX
7-
* The bundle can be split into smaller chunks where the most important ones can be loaded first and then every other secondary are lazily loaded, so called **code splitting**
5+
* Bundling your application is great, but as your app grows, your bundle size will grow too, especially if you include large 3rd party libraries
6+
* This may have a huge impact on the time to first load and UX, especially on slow networks
7+
* The bundle can be split into smaller chunks where the most important ones can be loaded first and then every other secondary are lazily loaded - **code splitting**
88

99
### What Is Code Splitting
1010

1111
* Multiple bundles are created that are loaded dynamically, only at the time they are needed
12-
* Enables to **lazy-load** just the components that are currently needed by the user
1312
* Can significantly improve performance of your app
1413

1514
### React.lazy
@@ -48,10 +47,11 @@ const MyComponent = () => (
4847
);
4948
```
5049

51-
* lazy() Takes a function that calls the dynamic `import()` => it must return a Promise which resolves to a module containing a React component
50+
* lazy() Takes a function that calls the dynamic `import()` - that must return a Promise which resolves to a module containing React component
5251
* Using lazy loaded component on its own **will throw an error**, we have to wrap it in Suspense component
53-
* But besides that we can use lazy loaded component the same way we use standard components
54-
* NOTE: React.lazy supports only default exports, if you want to use named exports, you must use intermediate module that reexports it as the default
52+
* But besides that, we can use lazy loaded component the same way we use standard components
53+
* React.lazy supports only default exports, if you want to use named exports, you must use intermediate module that reexports it as the default
54+
* lazy() and Suspense is [not yet available for server-side rendering](https://reactjs.org/docs/code-splitting.html#reactlazy)
5555

5656
### Suspense
5757

@@ -72,8 +72,8 @@ const MyComponent = () => (
7272
```
7373
7474
* You can place the `Suspense` anywhere above the lazy loaded component
75-
* It doesn't matter how deep is the lazy loaded component nested, it works similar to try-catch syntax - first Suspense component up in the component tree will catch the dynamic content and display fallback
76-
* You can wrap multiple lazy components inside a single `Suspense` component => it will display fallback until all dynamic components are loaded. Try to **avoid multiple spinners next to each other**
75+
* It doesn't matter how deep the lazy loaded component is nested, it works similar to try-catch syntax - first Suspense component up in the component tree will catch the dynamic content and display fallback
76+
* You can wrap multiple lazy components inside a single `Suspense` component => it will display fallback until all nested dynamic components are loaded. Try to **avoid multiple spinners next to each other**
7777
* Replaces [react loadable](https://github.com/jamiebuilds/react-loadable)
7878

7979
```javascript
@@ -117,7 +117,7 @@ const App = () => (
117117
);
118118
```
119119

120-
> Exercise 1 => [use Suspense with lazy()](./exercise/src/App.js)
120+
> Exercise 1 => [Use Suspense with lazy()](./exercise-lazy/src/App.js)
121121

122122
***
123123
**What we've gone through until now is in the production, from now on we will talk about the future**
@@ -147,59 +147,66 @@ const Img = ({src, alt, ...props}) => {
147147
// if no image with given source is found in the resource (cache), this line will throw a promise:
148148
ImageResource.read(src);
149149
150-
// And this line will have to wait until that promise resolves:
150+
// When the promise is resolved, the component's render will be called again and
151+
// this time ImageResource.read(src) will not throw (resource is already cached)
152+
// and component will be rendered
151153
return <img src={src} alt={alt} {...props} />;
152154
};
153155
```
154156
155-
We can use `Img` component inside `Suspense` as simply as:
157+
And use `Img` component inside `Suspense` as simply as:
156158
157159
```javascript
158160
<Suspense fallback={<div>I am downloading the image...</div>}>
159161
<Img src="https://path/to/image.jpg" alt="My image" />
160162
</Suspense>
161163
```
162164
163-
React.Suspense has a componentDidCatch sort of mechanism which will catch the promise thrown by `ImageResource.read()` and show a fallback until the promise is resolved
165+
* React.Suspense has a componentDidCatch sort of mechanism which will catch the promise thrown by `ImageResource.read()` and show a fallback until the promise is resolved.
166+
* To extend this to include an API call to get the URL of an image is easy, let's try it:
164167
165-
> Demo
168+
> Exercise 2 => [Use Suspense with data fetch and images](./exercise-fetch/src/pages/kitties.jsx)
166169
167170
## Concurrent Mode (Asynchronous Rendering)
168171
169-
> "Concurrent Mode lets React apps be more responsive by rendering component trees without blocking the main thread." - Dan Abramov
172+
"Concurrent Mode lets React apps be more responsive by rendering component trees without blocking the main thread." - Dan Abramov
173+
174+
![Lifecycle Methods Overview](./images/concurrent_mode_explained.png)
175+
> [Source: Andrew Clark's twitter post](https://twitter.com/acdlite/status/977291318324948992)
170176
171-
* Formerly known as "Async mode", but "Concurrent mode" has been chosen eventually because it reflects more the ability to perform work on different priority levels
177+
* Formerly known as "Async mode", but "Concurrent mode" name has been chosen eventually because it reflects more the ability to perform work on different priority levels
172178
* Allows React to interrupt a long-running render (for example, rendering a new feed story) to handle a high-priority event (for example, text input or hover)
173-
* keeps your app responsive while rendering complex component trees
174-
* Also improves the user experience of Suspense by skipping unnecessary loading states on fast connections
175-
* Concurrent mode is the future of React, so far only in experimental state.
179+
* Keeps your app responsive while rendering complex component trees
180+
* Allows Suspense to skip unnecessary loading states on fast connections (flashing spinners)
181+
* Concurrent mode is the future of React, but so far only in experimental state.
176182
* In Road map planned for Q2 2019
177183
* No documentation yet
178184
179-
What's possible in Async mode? E.g. skipping unnecessary loading states on fast connections when using Suspense.
180-
When we use lazy loaded components, small delay in load is not noticeable by user. There is a threshold - if the component load is delayed, but it still loads "fast enough", then it's counterproductive to display the spinner - it can harm **perceived** performance of the app.
185+
If you want to know more about how the concurrent mode is implemented, check out `fiber` and `algebraic effects`
181186
182187
### Enabling The Concurrent Mode
183188
189+
Instead of
190+
184191
```javascript
185-
import React from 'react';
186-
import ReactDOM from 'react-dom';
187-
import App from './App';
192+
ReactDOM.render(<App />, document.getElementById('root'));
193+
```
188194
195+
simply use:
196+
197+
```javascript
189198
ReactDOM
190199
.createRoot(document.getElementById('root'))
191200
.render(<App />);
192201
```
193202
194-
### maxDuration
195-
196-
maxDuration prop of Suspense in concurrent mode defines the time in ms after which our fallback component will show up. This will avoid screen flickering issue which usually occurs on faster network where the loader shows up for few ms and then the data comes immediately.
203+
This will allow to use new features, e.g. maxDuration prop of Suspense - it defines the time in ms after which our fallback component will show up. This will avoid screen flickering issue which usually occurs on faster network where the loader shows up for few ms and then the data comes immediately.
197204
198205
### Important Changes In React With Concurrent Mode
199206
200-
Use `<React.StrictMode>` to reveal potential problems after enabling concurrent mode - [see more here](https://reactjs.org/docs/strict-mode.html#identifying-unsafe-lifecycles)
207+
As render can be called multiple times in Concurrent Mode, some methods are no longer safe to use. Wrap your application in `<React.StrictMode>` to reveal potential problems - [see more here](https://reactjs.org/docs/strict-mode.html#identifying-unsafe-lifecycles)
201208
202-
Following lifecycle methods will be deprecated in future versions of React and can be problematic with Concurrent Rendering:
209+
Following lifecycle methods will be deprecated in future:
203210
204211
* `componentWillMount`
205212
* `componentWillReceiveProps`
@@ -211,20 +218,20 @@ Two new lifecycle methods will be added as a replacement:
211218
* `getDerivedStateFromProps`
212219
213220
![Lifecycle Methods Overview](./images/concurrent_lifecycle_methods.jpeg)
221+
> [Source: Dan Abramov's twitter post](https://twitter.com/dan_abramov/status/981712092611989509/photo/1)
214222
215-
## Notes
216-
217-
* lazy() and Suspense is [not yet available for server-side rendering](https://reactjs.org/docs/code-splitting.html#reactlazy)
218-
219-
## Conclusion
220-
221-
* Great solution for code splitting and improving UX
222-
* Concurrent mode in early development so far, but it is the future of React
223+
***It's crucial to have your render methods/functions pure, without any side effects!***
223224
224225
## Sources and Further Reading
225226
226-
* [Code Splitting the React app - official documentation]([https://reactjs.org/docs/hooks-intro.html](https://reactjs.org/docs/code-splitting.html))
227+
### Talks
228+
227229
* [Andrew Clark's talk on React Suspense](https://www.youtube.com/watch?v=z-6JC0_cOns)
228230
* [Dan Abramov's talk on React Suspense](https://www.youtube.com/watch?v=6g3g0Q_XVb4) from ReactFest
229231
* [Jared Palmer's talk on React Suspense](https://www.youtube.com/watch?v=SCQgE4mTnjU) from React Conf 2018
230-
* [Talk of Andrew Clark and Brian Vaughn on Concurrent Rendering in React](https://www.youtube.com/watch?v=ByBPyMBTzM0) from React Conf 2018
232+
* [Talk of Andrew Clark and Brian Vaughn on Concurrent Rendering in React](https://www.youtube.com/watch?v=ByBPyMBTzM0) from React Conf 2018
233+
234+
### Articles And Documentation
235+
236+
* [Code Splitting the React app - official documentation]([https://reactjs.org/docs/hooks-intro.html](https://reactjs.org/docs/code-splitting.html))
237+
* [Marvin Frachet - React-cache, time slicing, and fetching with a synchronous API](https://medium.freecodecamp.org/react-cache-time-slicing-and-fetching-with-a-synchronous-api-2a57dc9c2e6d) => advanced reading on how is the concurrent mode implemented

0 commit comments

Comments
 (0)