11// LIBRARY IMPORTS
2- import React , { Component } from "react" ;
2+ import React , { Component , Suspense } from "react" ;
33import { Route , NavLink , Switch , Redirect } from 'react-router-dom' ;
44
55// STYLING IMPORTS
66import "./Blog.css" ;
77
8- /**
9- * One concept, which is very important, and easy to implement,
10- * is Code Splitting (aka Lazy Loading), where we load routes/
11- * components that we don't require all the time, to be loaded
12- * when they're required (or when they're requested for by the
13- * user).
14- *
15- * Without Lazy Loading, what we generally do is, we try to
16- * get the entire `bundle.js` file whenever we request for the
17- * webapp. For smaller webapps, loading the entire app makes
18- * sense. But if an application is extremely big, in that
19- * scenario, we might want to lazy load certain components
20- * when they're required/requested by the user. Such components
21- * in the webapp generally exits for different routes, or
22- * sometimes, at the component level itself. The solution is to
23- * lazy load such components/routes entirely, using the new ES6
24- * async import() method.
25- *
26- * We generally create a HOC inside which we basically pass an
27- * component, which would be loaded lazily (asynchronously),
28- * which is the HOC created as a LazyLoader inside the `hoc`
29- * directory in our webapp.
30- *
31- * For this lazy loading example, we will set the state for
32- * `auth` to true, so that we have access to the "/new-post"
33- * route. This "/new-post" route can be lazy loaded, only when
34- * the user wants to post a new post onto the database.
35- * Therefore, loading the component related to the "/new-post"
36- * route is unnecessary, and so, we need not load the component
37- * related to "/new-post" route upfront, instead, we can always
38- * lazy load the respective component and its child components
39- * when the user wants/needs it.
40- *
41- * This technique of downloading/acquiring a resource
42- * (component in this case) only when needed by the end-user,
43- * is known as Code Splitting (or) Lazy Loading.
44- *
45- * NOTE: Code Splitting is heavily dependent on the WEBPACK
46- * configuration. The Webpack config generated from the
47- * `npx create-react-app` command, has a webpack configuration
48- * which supports the implementation of code splitting as shown
49- * in here.
50- */
51-
528// CUSTOM COMPONENTS
53- /**
54- * Direct imports inform Webpack (The Build Tool used BTS) that
55- * this particular component that's being imported, is a
56- * dependency which is to be included directly inside
57- * `bundle.js` file (which is the final file to deployed).
58- *
59- * For Lazy Loading, we don't want to import the component
60- * (or resource) directly, as shown above for React and
61- * Component (or for Posts as shown below), but we want to
62- * load it only when needed.
63- *
64- * For that, we need to prepare Webpack to dynamically bundle
65- * some extra resource/component for this potentially loaded
66- * code.
67- *
68- * Therefore, to import the <NewPost /> component dynamically
69- * (for lazy loading on "/new-post/" route), we will import the
70- * HOC which lazy loads the required component passed to the
71- * dynamic import() method, and returns the respective
72- * component related to the specified module which is mentioned
73- * as a parameter to the dynamic import() method.
74- */
759import Posts from '../../containers/Blog/Posts/Posts' ; // direct import
7610// import NewPost from './NewPost/NewPost';
77- import asyncLazyLoadComponent from '../../hoc/LazyLoader/asyncLazyComponent' ;
11+ // import asyncLazyLoadComponent from '../../hoc/LazyLoader/asyncLazyComponent';
12+
13+ /**
14+ * Instead of using our own custom-made HOC, from React v16.6,
15+ * we can use React.lazy() method and replace what our
16+ * asyncLazyLoadComponent() method did. The lazy() method also
17+ * takes in an anonymous callback function which returns a
18+ * call to the dynamic import() method, which returns a Promise
19+ */
7820
7921// this following line is a dynamic import using the import()
80- const AsyncNewPost = asyncLazyLoadComponent ( ( ) => import ( './NewPost/NewPost' ) ) ;
22+ // const AsyncNewPost = asyncLazyLoadComponent(() => import('./NewPost/NewPost'));
23+
24+ // Instead of the using our custom HOC for lazy loading the
25+ // <NewPost /> component, we can now use React.lazy() as shown
26+ // below.
27+ const AsyncNewPost = React . lazy ( ( ) => import ( './NewPost/NewPost' ) ) ; // only supports default exports.
28+
29+ /**
30+ * Now, we will render the <NewPost /> which is now our
31+ * <AsyncNewPost /> component inside a <React.Suspense />
32+ * Component as shown in the `render` prop of the <Route />
33+ * component defined for the "/new-post" `path` below (line #72)
34+ */
8135
8236class Blog extends Component {
8337 state = { auth : true } ;
84-
8538 render ( ) {
8639 return (
8740 < div className = "Blog" >
@@ -115,16 +68,16 @@ class Blog extends Component {
11568 </ ul >
11669 </ nav >
11770 </ header >
118- {
119- /**
120- * Now, we can use the <AsyncNewPost /> component
121- * that we will get dynamically, only when the
122- * component related to the "/new-post" route is
123- * routed/clicked by the user.
124- */
125- }
12671 < Switch >
127- { this . state . auth ? < Route path = "/new-post" component = { AsyncNewPost } /> : null }
72+ { this . state . auth ?
73+ < Route
74+ path = "/new-post"
75+ render = { ( ) =>
76+ < Suspense fallback = { < div style = { { textAlign : 'center' } } > Loading...</ div > } >
77+ < AsyncNewPost />
78+ </ Suspense >
79+ }
80+ /> : null }
12881 < Route path = "/posts" component = { Posts } />
12982 < Route render = { ( ) => < h1 style = { { textAlign : 'center' } } > 404 Not Found</ h1 > } />
13083 { /*<Redirect from="/" to="/posts" />*/ }
@@ -138,14 +91,12 @@ class Blog extends Component {
13891export default Blog ;
13992
14093/**
141- * Now, whenever we click on the "New Post" link (or get
142- * routed to "/new-post" route), we might not see any changes
143- * upfront, but if we open the `Network` tab of the Dev Tools
144- * of our browser, and then see what is happening when we go
145- * to the "/new-post" route for the first, we can see that we
146- * are actually downloading the required JS file as a small
147- * chunk from the server (thanks to HTTP v2) asynchronously.
94+ * VERY IMPORTANT (README) on React.lazy() & <React.Suspense />
95+ * ------------------------------------------------------------
14896 *
149- * Whereas, before lazy loading the <NewPost /> component, we
150- * were getting it inside the bundle.js file at once.
97+ * We can use lazy loading for any component using
98+ * React.lazy() method along with the <React.Suspense />
99+ * wrapper. We can use it even for loading components which
100+ * aren't rendered from the <Route /> component defined
101+ * inside the <BrowserRouter /> component.
151102 */
0 commit comments