All posts by admin

React Context

ref – https://www.taniarascia.com/using-context-api-in-react/
https://www.toptal.com/react/react-context-api

React Context solves one major problem: prop drilling.

Prop drilling is the processing of getting data from component A to component Z by passing it through multiple layers of intermediary React components. Component will receive props indirectly and we have to ensure all the data gets the latest update.

So if a child component changes data, then we have to make sure its grand children and parents gets this updated data. This can lead to too much data tracking work.

In a few words, the Context API allows you to have a central store where your data lives (yes, just like in Redux). The store can be inserted into any component directly.

Provider – The component that provides the value
Consumer – A component that is consuming the value

Update 2023

Context is a place where we create all the data that we want our children to be able to use.

First we create a context with initial data by using react’s createContext.

Now, we use this SettingsContext so that we can access its Provider property like this SettingsContext.Provider
This is so that we can give data to its value. This value is kept so that children components can access them.

We do all of the mentioned in a functional component like so:

And so we use it in our index file like so:

src/index.js

In order to set up usage in our children components, we get useContext, and insert our SettingsContext functional component in there, in order to return a hook.

src/hooks/useSettings.js

2020

Creating the Context

First, we need to create the context, which we can later use to create providers and consumers.

src/UserContext.js

Providing Context

The provider always needs to exist as a wrapper around the parent element, no matter how you choose to consume the values. I’ll wrap the entire App component in the Provider. I’m just creating some value (user) and passing it down as the Provider value prop.

src/App.js

Now any child, grandchild, great-grandchild, and so on will have access to user as a prop. Unfortunately, retrieving that value is slightly more involved than simply getting it like you might with this.props or this.state.

Consuming Context

The way you provide Context is the same for class and functional components, but consuming it is a little different for both.

Class component way

The most common way to access Context from a class component is via the static contextType. If you need the value from Context outside of render, or in a lifecycle method, you’ll use it this way.

src/HomePage.js (class example)

Functional component and Hooks

For functional components, you’ll use useContext, such as in the example below. This is the equivalent of static contextType.

src/HomePage.js

Updating Context

Updating context is not much different than updating regular state. We can create a wrapper class that contains the state of Context and the means to update it.

We create a Provider that connects a getter/setter to the UserContext.

In other components, these methods are then extracted from UserContext, and used to change the context value.

src/UserContext.js

Let’s create a component, use this UserProvider

React App – Breaking Bad API

ref – https://www.youtube.com/watch?v=YaioUnMw0mo

final source

Getting Started


create-react-app breaking-bad
cd breaking-bad
npm start

the server should start on localhost:3000

Can can remove:

– Tests.js
– serviceWorker.js
– App.test.js
– index.css

In index.jsn and App.js, remove the code where it imports the files we’ve just deleted.

index.js

In App, we change the function to es6 syntax. However, it still remains a functional component. A functional component is just a plain JavaScript function which:

– accepts props as an argument
– returns a React element.
– DOES NOT have state. Thus, you cannot use setState()
– No lifecycle methods.

In our case, we don’t accept any props, and we return a simple div React element. Also, no state, no lifecycle methods.

In App.css, remove all the default styling. It should be empty.

Go back to browser, should only see ‘hello’.

Import own resources

Now you can incorporate your own resources: avatar, background, and a spinner image.

Open up your App.css, and paste in your custom styles. I used a random styles from a template I downloaded from the web.

In App.css, remove all the default styling. We copy and paste our code from custom .css.

We then create an img folder and put bg.jpg, avatar.jpg, and a spinner image in there.
We also create components folder. Create ui folder inside of that. And then create an empty Header.js file.

Run the app. Go back to browser, should only see a blank page with ‘hello’ text.

In src, create components folder.

create subfolder UI, create Header.js. We create a functional component that returns an empty div.

We import out logo so that it appears in our header. Stick it in a img tag.

We then import it into our App.

Finally, in your App.css, update the location of the background image.

Also, remove an import of font-awesome at the very top of the css file.

So when you refresh the app, you should see our Header component. Look at the DOM, all the code should match up.

Using Hooks

Originally, we cannot use state because we’re a functional component. In order to do so, we must convert it to a class component. But now with hooks, we can declare get/set functions that manipulates the state object in function components.

By using useEffect, you tell React that your component needs to do something after it calls render. We tell React our ‘effect’ will run after React flushes all the changes to the DOM. React will then run your effect function after it performs all the DOM updates.

Your useEffect function will be executed after each render, and after every setState/update.

If we return a function inside of useEffect, it’s the ‘unmounting’ effect we want to run when the component WILL Un mount. The effect function we declare in the useEffect’s anonymous function body is what we want to run with the component DID mount.

Let’s update our App.js file like so:

We first declare all the get/set for the items to contain the incoming data, and also isLoading for displaying the busy icon.

We use built-in fetch function to retrieve the data. It will return a Promise with a resolved mixin BODY object. We call json on it, and it’ll return a Promise with an array of data for us to use.

Setting up the Character Grid

Under components, create folder for characters. Then create CharacterGrid.js:

We created a functional component that takes in a prop. We use destructure to extract items, and isLoading. From there we simply display the data from items.

In App.js, make sure you have passed in the data to CharacterGrid:

Now you should see the names successfully being displayed along with the CSS applied.
Notice in your console, you get an error that says something like: index.js:1 Warning: Each child in a list should have a unique “key” prop.

This means when you display an array of data, React needs to identify them by a special unique string. This way, it knows where to match the string with the list item. Luckily for us, we get special IDs in our data array. We can just use that instead. Note to never use index. If React uses index to match a particular string to a list item, then the strings would pop to wrong places. (i.e. If you add an item at the top, React would always make the string that go matched with index 0 to appear at the very top) don’t use index as key

Refactor

Looking at CharacterGrid, it seems like the component may take on a lot more responsibilities in the future. Let’s take the load off by making a component that strictly displays data, whereas CharacterGrid can take care of mapping the data and other logic.

We’ll call this display component CharacterItem.js:

CharacterGrid.js

Search

Let’s create a search component. Under folder src > components > ui, let’s create Search.js

Then in your App.js

Creating a controlled component

Form elements (like input) maintain their own state. In React, we have mutable state objects and updated with setState().

So the situation is that we have two separate state: React’s, and input’s.

We can combine the two by making the React state to be ‘single source of truth’. This means we get input element’s value to be controlled by React’s state object.

Hence we make this into a controlled component by doing:

1) create state object’s text property (parent component)
2) child component has input state. It gets latest from parent via prop.
3) child component’s input’s onChange will receive event obj’s target.value. We use prop callback to update parent component’s text property.
4) Finally, make sure we pass text property, and also the callback from parent component to child component. This way child component can get the latest text query, and also update parent when its input has been updated.

This is one of the ways to solve the issue of the parent having state, the child having state, and thus trying to update multiple versions of the state. We call this

In order to test this, simply display text in your JSX.

Search.js

Notice all state is here in this parent component. We pass what needs to be displayed into Search, which is text property. We then get the updated user inputted text from search and update our state object via callback getQuery. In getQuery, we simply update the text (which is for display) and query (which is for query string). This is how a controlled component solves problems of multiple versions of state.

App.js

As you can see, whatever we type into our form, will be updated in property ‘text’ via setText.

Querying API using updated input from users

Now let’s update App.js:

App.js

In the useEffect’s second parameter, if we put absolutely nothing, useEffect only gets called once because one effect will follow one render. When we call useEffect, we tell React to run our effect after flushing changes to the DOM. Hence we wait until everything is flushed to the DOM, before we execute our first useEffect.

For example, Query is empty so we retrieve data from online API. We then set items, which will trigger a re-render. EVERY TIME we re-render, we schedule a different useEffect, replacing the previous one. AKA, each effect belongs to a particular render. They get paired up.

But in our particular example, notice we call setItems and setIsLoading. We’re setting state in useEffect, which will cause a render again. That render gets paired with a useEffect, which then calls setItems/setIsLoading again….useEffect –> setStates –> renders –> useEffect –> setState… repeat infinitely.

So in our particular example, it ends up going into an infinite loop.
React hooks

If we only put [], useEffect will only fire once. It won’t look for any changes in any specified properties to re-render. If we put [query], whenever the query change, useEffect will fire. But if the previous and current state are the same, then React will bail out and won’t re-render.

If we put [query], whenever the query change, useEffect will fire. But if the previous and current state are the same, then React will bail out and won’t re-render.

Now when you type out a search text, React will take the text and query the API for the latest results and populate it onto the UI screen.



Spinner

Import a spinner image.
Under src/components/ui, create Spinner.js:

In your CharacterGrid.js, replace the waiting h1 tag, with our Spinner component:

Now when you refresh, you’ll see a spinner while the data is being retrieved. Once the app gets the data, it removes the spinner and displays the content.

Fetch Data and display in a React component

we use built-in fetch to get data from a url say…https://api.example.com/items:

Once we have retrieved it, we execute json() on the response ‘res’, which is a JSON BODY mixin.

It returns a promise that resolves with the result of parsing the body text as JSON:

We then set our state object property employees to that result. When we use setState, React sees that a state property was updated, and goes to diff the virtual DOMs. Thus, the render gets triggered again so that we re-draw the subtree that changed.

Notice we put the fetch inside of componentDidMount. The reason why is because the component needs to execute constructor, componentWillMount, then start building up its DOM, and finally when done, call componentDidMount first in order to have the states and nodes in place. Only when our DOM nodes and states are ready, can we then insert data. Thus, that is why we fetch in componentDidMount.

full code

What is the benefit of styles modules?

It is recommended to avoid hard coding style values in components. Any values that are likely to be used across different UI components should be extracted into their own modules.

For example, these styles could be extracted into a separate component:

And then imported individually in other components:

import { space, colors } from ‘./styles’

What are the common folder structures for React?

There are two common practices for React project file structure.

Grouping by features (or routes)

One common way to structure projects is locate CSS, JS, and tests together, grouped by feature or route.


common/
├─ Avatar.js
├─ Avatar.css
├─ APIUtils.js
└─ APIUtils.test.js
feed/
├─ index.js
├─ Feed.js
├─ Feed.css
├─ FeedStory.js
├─ FeedStory.test.js
└─ FeedAPI.js
profile/
├─ index.js
├─ Profile.js
├─ ProfileHeader.js
├─ ProfileHeader.css
└─ ProfileAPI.js

Grouping by file type

Another popular way to structure projects is to group similar files together.

api/
├─ APIUtils.js
├─ APIUtils.test.js
├─ ProfileAPI.js
└─ UserAPI.js
components/
├─ Avatar.js
├─ Avatar.css
├─ Feed.js
├─ Feed.css
├─ FeedStory.js
├─ FeedStory.test.js
├─ Profile.js
├─ ProfileHeader.js
└─ ProfileHeader.css

How to programmatically trigger click event in React?

You could use the ref prop to acquire a reference to the underlying HTMLInputElement object through a callback, store the reference as a class property, then use that reference to later trigger a click from your event handlers using the HTMLElement.click method.

This can be done in two steps:

Create ref in render method:

Apply click event in your event handler:

Render Props

ref – https://reactjs.org/docs/render-props.html
https://flaviocopes.com/react-render-props/

A common pattern used to share state between components is to use the children prop.

For example, a component’s (this.props.children) references the JSX that you pass into this particular component.

In our case, component Parent’s this.props.children references an array which contains Children1 and Children2 components.

However, there is a problem here: the state of the parent component cannot be accessed from the children.

so we share state like this:

In the Parent, we have a state object with property ‘name’. We pass this into this.props.children
Thus, whatever we pass into JSX Parent component will be able to receive Parent’s state via prop:

However, using the children property on the prop object is very specific. You may not want this.

Render Prop

You have the option to use any prop. We can use someProp1, someProp2 as props in component Parent. It takes in data which we then pass to components Children1 and Children2.

So in component Parent, this.props.someprop1 references function

Then, this.state.name is passed into into this.props.someprop1 in the render function.

This name then goes into the function above and gets passed into component Children1.

Thus, the name ‘Flavio’ is passed into component Children1.

This is called render prop, which refers to a technique for sharing code between React components using a prop whose value is a function.

In other words, a component (Parent) with a render prop (someprop1) references a function:

In our case the function is:

that returns component Children and is called in Parent’s render function:

More concretely, a render prop is a function prop that a component uses to know what to render.

getDerivedStateFromProps

ref – https://alligator.io/react/get-derived-state/
https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html

For a long time, the lifecycle componentWillReceiveProps was the only way to update state in response to a change in props without an additional render. In version 16.3, we introduced a replacement lifecycle, getDerivedStateFromProps to solve the same use cases in a safer way.

getDerivedStateFromProps improves on the older method by providing a function whose only purpose is to update the state based on prop changes, without any side effects.

getDerivedStateFromProps simply returns an object containing the updated state. Notice that the function has no side-effects; this is intentional. Depending on how you want to update the state based on prop, you return an object literal.

getDerivedStateFromProps may be called multiple times for a single update, so it’s important to avoid any side-effects. Instead, you should use componentDidUpdate, which executes only once after the component updates.

However, you probably don’t need Derived State

When to Use Derived State

getDerivedStateFromProps exists for only one purpose: It enables a component to update its internal state as the result of changes in props.

All problems with derived state that we have seen can be ultimately reduced to either:

(1) unconditionally updating state from props or
(2) updating state whenever props and state don’t match.

YOU DON”T NEED DERIVED STATE

– If you’re using derived state to memoize some computation based only on the current props
– If you’re updating derived state unconditionally or updating it whenever props and state don’t match, your component likely resets its state too frequently.

The terms controlled and uncontrolled usually refer to form inputs, but they can also describe where any component’s data lives.

Data passed in as props can be thought of as controlled (because the parent component controls that data). Data that exists only in internal state can be thought of as uncontrolled (because the parent can’t directly change it).

The most common mistake with derived state is mixing these two. For example:

State value can be updated by setState calls, as well as derived from prop. This means there isn’t a single source of truth for the data.

Unconditionally copying props to state

State is initialized to the value specified by props and updated when we type into the input. But if our component’s parent re-renders, anything we’ve typed into the input will be lost! Components usually accept multiple props; another prop changing would ALSO cause a re-render and improper reset.

Therefore, it is a bad idea to unconditionally copy props to state.

Erasing state when props change

We’ve just made a big improvement. Now our component will erase what we’ve typed only when the props actually change.

However, because our prop uses ’email’ property compare, if two accounts had the same exactly email, this situation would happen.

1) Say you’re updating the first email account, then you click on another account type.
2) The parent component’s prop makes the update, but because your email is the same “fake.email@example.com” for id 1 and id 2, our componentWillReceiveProps will just skip. When users switch from id 1 to id 2, they still see what you updated in the input text. Whereas it should have cleared, or defaulted by to the string “fake.email@example.com”.

The key is that for any piece of data, you need to pick a single component that owns it as the source of truth, and avoid duplicating it in other components. Let’s take a look at each of the alternatives.

Solutions

Fully controlled component – One way to avoid the problems mentioned above is to remove state from our component entirely. If the email address only exists as a prop, then we don’t have to worry about conflicts with state.

This approach simplifies the implementation of our component, but if we still want to store a draft value, the parent form component will now need to do that manually.

Fully uncontrolled component with a key

In order to reset the value when moving to a different item, we can use the special React attribute called key. When a key changes, React will create a new component instance rather than update the current one. Keys are usually used for dynamic lists but are also useful here. In our case, we could use the user ID to recreate the email input any time a new user is selected:

Each time the user id changes, the EmailInput will be recreated and its state will be reset to the latest defaultEmail value.

But let’s say the component is very expensive to initialize, and we can’t create it often…

A workable but cumbersome solution would be to watch for changes to “userID” on property “prevPropsUserID” in getDerivedStateFromProps:

React.memo, React.useMemo, React.useCallback

ref – https://dev.to/dinhhuyams/introduction-to-react-memo-usememo-and-usecallback-5ei3
https://medium.com/javascript-in-plain-english/react-usememo-and-when-you-should-use-it-e69a106bbb02
https://dmitripavlutin.com/dont-overuse-react-usecallback/

React.memo IS NOT A HOOK. React.memo is a higher order component.
It’s the same to React.PureComponent , but for function components instead of classes.

Where as React.useMemo is a hook.

If your function component renders the same result given the same props,
you can wrap it in a call to React.memo for a performance boost in some cases
by memoizing the result. This means that React will skip rendering the component,
and reuse the last rendered result.

React.memo only checks for prop changes. If your function component wrapped
in React.memo has a useState or useContext Hook in its implementation,
it will still re-render when state or context change.

We have an App with two different states, count1 and count2.

We then return a React Element with two components that uses these counts as props

As you can see, even though we click on the button to increase Counter Won’s state property count1, Counter Too gets re-rendered as well. This is because React sees that state has changed, it will re-render the whole whole element.

The heuristic algorithm says that as long as the node types are the same, then recursively update.

Hence, our main div stays the same.
The header stays the same.
Button stays the same because it’s just a click handler.
Counter Won’s state changed from 0 to 1, so we update it.
Counter Too’s state stayed the same, update also.

So the problem is here.
“Counter Too” re-renders simply because a state from Counter Won has changed which makes App re-render.

In order to separate this, we can use React.memo to control our re-rendering scheme. So instead of all instances of Counter components under a React Element being re-rendered simply due to one state change, we can have it where by default.

If your component renders the same result given the same props, you can wrap it in a call to React.memo for a performance boost in some cases by memoizing the result. This means that React will skip rendering the component, and reuse the last rendered result.

React.memo only checks for prop changes. If your function component wrapped in React.memo has a useState or useContext Hook in its implementation, it will still rerender when state or context change.

If these props are unchanged, React.memo will reuse the last rendered result, therefore, it prevents the component from being re-rendered. In our example, React.memo will check if there are any changes with the value and children props since the last render. Since our button only changes the value of the counter1, React.memo will prevent the counter2 from being re-rendered.

In Counter.js

If you want to use your own logic for the re-rendering

There is an example at the end here

React.useMemo

useMemo is a hook that (given a function, and an array of values) returns a memoized value. It takes a function that does some calculations. When said properties have been changed, then it recalculates the function. If they stay the same, then we don’t recalculate and simply return what was memoized from before.

The hook will return a new value only when one of the dependencies value changes (referential equality).

React.useMemo Example

We have two functional component: FibDisplay and NameDisplay.
FibDisplay has prop property length. It is connected to state length.
NameDisplay has prop property name, it is connected to state name.

Run the app. Say we update name. We set_name a new value from input. This update will trigger a re-render for all components in our App’s render, including the FibDisplay component.

However, FibDisplay component re-render is very expensive because it does a lot of calculations.

Can we somehow improve this performance?

In order to do so, we can have React memo-ize the calculations of our fib:

It will remember the value we have calculated as the result if our previous prop and current prop match.

Then when we re-run the app, you’ll notice that we still re-render FibDisplay, however, const numbers will not be re-calculated again.

All you’ll see is the React components being re-rendered. But no expensive Fib computations.

– The hook itself introduces new complex logic, and it might introduce more performance issues than it solves. Do not apply useMemo unless this is a really expensive computation, or, if you are not sure, you can benchmark both ways and make an informed descision.

– As per the React docs, you may never depend on the internal mechanisms on useMemo. In other words, while useMemo is supposed to be called only on dependencies change, this is not guaranteed. Your app must still work perfectly well (maybe a bit slow though) if useMemo calls your callback on every render.

Differences between useMemo and useEffect

  • useState is causing a re-render on the call of the setState method (second element in the array returned). It does not have any dependencies like useMemo or useEffect.
  • useMemo only recalculates a value if the elements in its dependency array change (if there are no dependencies – i.e. the array is empty, it will recalculate only once). If the array is left out, it will recalculate on every render. Calling the function does not cause a re-render. Also it runs during the render of the component and not before.
  • useEffect is called after each render, if elements in its dependency array have changed or the array is left out. If the array is empty, it will only be run once on the initial mount (and unmount if you return a cleanup function).

useCallback

Different function instances sharing the same code are often created inside React components.

When inside a React component body a function is defined (e.g. a callback or event handler), this function is re-created on every rendering:

In other words…

handleClick is a different function object on every rendering of MyComponent.

When we pass button handler functions to props of child components:

Because inline functions are cheap, the re-creation of functions on each rendering is not a problem. A few inline functions per component are acceptable.

However, there are cases when you need to keep one instance of a function:

– A component wrapped inside React.memo() (or shouldComponentUpdate) accepts a callback prop
– When the function is used as a dependency to other hooks, e.g. useEffect(…, [callback])

That’s the case when useCallback(callbackFun, depends) helps you: giving the same dependency values depends, the hook returns the same function instance between renderings:

Imagine you have a component that renders a big list of items:

MyBigList renders a list of items. Knowing the list could be big, probably a few hundreds of items. To preserve the list re-rendering, you wrap it into React.memo.

The parent component of MyBigList needs provides a handler function when an item is clicked.

handleClick callback is memoizied by useCallback(). As long as term variable stays the same, useCallback() returns the same function instance.

Even if for some reason MyParent component re-renders, handleClick stays the same and doesn’t break the memoization of MyBigList.

A bad use case would be if a components simply returns very little JSX.

Another example

where Counter component is:

Now, when App is rerendered, a new increaseCounter1 function object is passed into onClick.
ref – https://stackoverflow.com/questions/39260595/event-handlers-in-react-stateless-components

const references are popped off the local stack when the function component have been used. Thus, when we re-render this function component again, it needs to re-create the const references and the objects that they point to.

By default, React.memo does does a shallow comparison of props and objects of props. Even so, because the onClick handlers are being recreated, our child component Counter will always see that the previous and current prop’s onClick handlers are referencing different objects. Thus, it will always re-render Counter2, even if we only update Counter1’s state.

The easy way to avoid this issue is to prevent the increaseCounter2 function from being recreated when the App is re-rendered.

We make use of React.useCallback to do this:

Now, when you run it, there will only be one handler function. That way, functional component Counter will get the same previous and current function object. Thus changing Counter 1’s state will only re-render Counter1. Counter2 will be untouched.