Chapter 08
Chapter 08
Nested Paths :-
A path inside another path. It can be created by making a children array for an already existing children. Ex :-
In the 1st layer of children, we are specifying path with the suffix “/”,
which denotes root (like -> “/about”). We could have also written
“about” instead and it would work just fine because the parent path is
already specified as root (since it’s written path: “/” ).
However, in the nested path, always write just the name in the path
argument (like :- path: ”profile”), and not path: “/profile”. This is because
in the latter one, the actual path will be treated as
“localhost:1234/profile”, since as stated earlier, “/” denotes root path.
However, in the former case, the actual path will be
“localhost:1234/about/profile”.
But, this syntax will just show the About component only and not the
Profile component.
This is because, children are always rendered within an Outlet component and Outlet should be created inside the parent.
This was done just for the sake of showing an example. We actually want our profile component to be always present in our
About component, so we will just import our Profile component and use it instead of the Outlet.
So, the constructor is called only once, but everytime the UI is updated, the render() function is definitely called.
Also, notice that in the new CBC code, we have imported the Component Class directly from react library.
Output 1 :- An Output to show the flow of how CBC components are called :-
First we render only the ProfileClass component in the About component and remove the Profile component. Then see the
below code and output :-
Output 2 :- Showing how multiple child CBCs are rendered from 1 parent CBC
When React is rendering things up i.e. when reconciliation happens, it does that in 2 phases :-
1. Render phase :- This phase includes the calling of constructor and render().
2. Commit phase :- The phase where React is actually modifying our DOM, and we know that the
componentDidMount() is called after we have updated the DOM (That is why we see the Skimmer effect)
To get a response from an API, we are using the fetch() function here, axios can also be implemented. Now, we know that
making an API call requires an async function. If you remember, in our RestaurantMenu.js, where we used useEffect(), we did
not make the callback function async. The reason is written at the bottom of this assignment, as to why we should not write
an async function as a callback in useEffect.
However, we can make the componentDidMount() an async function and fetch API data using fetch()/axios. To store the API
data, we have created another state variable named userInfo.
See the flow of output too :- (Left side is the About.js page i.e the Parent CBC and ProfileClass.js is the child CBC)
We know that React finishes our Render phase/cycle first and then goes to the commit cycle. That is why all things “Child
render ArpanClassChild 2” is printed first. Then, the componentDidMount() of the parent will get printed first because, that
of the children’s are async and they will take some data to load. Similarly, if we console log the json object too that stores our
response, in the componentDidMount of a child in ProfileClass.js and just render one child component instead of two in
About.js like :-
Now, if there are again 2 child CBC in the About.js, which is the parent CBC, with names “ArpanClassChild 1” and
“ArpanClassChild 2”, then below will be the output :-
Now, again we just use the “ArpanClassChild 1” and remove the 2nd one in the About.js, which is the parent CBC. However, if
we write the code of console logging the “Child componentDidMount” before making the API call like below, then we will get
a different output :-
Now, if there are again 2 child CBC in the About.js, which is the parent CBC, with names “ArpanClassChild 1” and
“ArpanClassChild 2”, then below will be the output :-
Remember this diagram :-
Here in the last few examples, when
we are doing this.setState() inside the
child’s componentDidMount(), we are
actually updating the component. So,
looking at the diagram you can say
that, at first the Mounting phase
happens. Here, the constructor is
called, then the render(). This
concludes the render phase of
Mounting. Then commit phase starts
where React updates the DOM with
the default component and
componentDidMount() is called. In our
example, in that function we have made an API call.
So, after the data is fetched from the API, the commit phase of the Mounting is also over.
Now, we actually use that data to update an existing component i.e. rendering the component with the help of setState(). So,
we enter the updating phase of the diagram.
In this, again the render() is called, which concludes the render phase of Updating. Then, the DOM is updated and
componentDidUpdate() is called (if present, in our examples it was not there).
This method will be called once our component is unmounted i.e. our component is no longer there in the webpage. In our
project it can be seen by writing the below piece of code, which will give the 1st output on entering the URL
“localhost:1234/about” or “localhost:1234/about/profile”. Now, in this page, the About component, along with its child
components (here ProfileClass component) is displayed in the webpage.
The moment we navigate to the Home/Contacts component from the navbar, we will see that the console log inside the
componentWillUnmount() gets printed.
NEVER EVER COMPARE REACT LIFE CYCLE METHODS TO FUNCTIONAL COMPONENT HOOKS
How to mimic the functionality of a dependency array in useEffect(), here in CBC?
The elements of the dependency array in useEffect() used to denote that whenever there is a change in any one those state
variables, the callback function of useEffect() will be called. In CBC, we know that the life-cycle method that gets called after
every update is the componentDidUpdate().
We know that normally, that method is called just after the initial render. So, it is like putting an empty dependency array.
But what if I want it to be called after a state variable is changed?
We pass 2 arguments :- prevProps and prevState.
In the below screenshot on the left side is the CBC named ProfileClass and on the leftside is the FC named Profile. In the FC,
we have a dependency array with 2 state variables :- count and count2. To mimic this functionality, we write that if-else piece
of code in the componentDidUpdate() -> it means that when the state of count or count2 changes, React has to execute the
given statements written inside the if block.
Now, if we wanted to execute 2 different tasks for changes in the state variable count and count2, then in CBC, we have to
write 2 different if blocks and in the FC, we have to write 2 different useEffect()s like :-
Now, if we navigate back to the About Page, we will be again calling the componentDidMount() method which has the
setInterval. So, now there will be 2 setIntervals running and if you notice the count of the statement in the console, you will
see that the count is increasing by 2 in every 1 sec.
The 1st image below shows the output when we are in the About page and
the 2nd image shows the output when we navigate to the Contacts page.
Mistakes every React developer should avoid (Also covers the cleanup) :-
https://www.youtube.com/watch?v=QQYeipc_cik&ab_channel=LamaDev
React follows a one-way data binding i.e. data flow only from parent to child, not reverse, at least in theory. But how to do
the reverse action? See this Link4
Why do we write super(props) and is there a problem in writing just super() ? -> Link5, Link6 (See the 1st answer)