Concepts of React JS — Part 2

📄 Table of Contents

➤Error handling in React 16

▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬ ✦ ✦ ✦ ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬

◉ setState()

  • When a state update occurs via setState(), it causes the component to re-render and the newly entered value is displayed in the element.
  • Caution, reading this.state immediately after setState is a potential pitfall, however consoling it will reflect correctly inside render() method. So, what if we want to access the new state after setState actually updates state?

perform setState and then console inside a callback function, as below:

this.setState({color: "red"},()=>{
console.log(this.state.color);
}

Passing setState a function gives us two benefits. The first is it allows us to take a static copy of our state that will never change on its own. The second is that it will queue the setState calls so they run in order.

why to use setState()

this.state.message = 'don't update state like this';

Updating the state in this way will NOT cause a re-render of the component and the changes made by the user will not be displayed in the UI.

◉ render.props()

But when a component with a render prop takes a function that returns a React element and calls it instead of implementing its own render logic.

The term render prop refers to a technique for sharing code between React components using a prop whose value is a function.

◉ React Fragment

Example:

Understanding the problem if React Fragment is not used −

Suppose we create a table −

class ExampleTable extends React.Component {
render() {
return (
<table>
<tr>
<ExampleColumns />
<tr>
</table>
);
}
}
class ExampleColumns extends React.Component {
render() {
return (
<div>
<td>col 1</td>
<td>col 2</td>
</div>
);
}
}

The actual syntax will include the div which we have added in the return statement of columns.

<table>
<tr>
<div>
<td>col 1 </td>
<td>col 2</td>
</div>
</tr>
</table>

Now, table tag is containing a div tag which is breaking the semantic of the html. So to avoid this we can simply replace the div with React.Fragment or in short <>.

class ExampleColumns extends React.Component {
render() {
return (
<>
<td>col 1</td>
<td>col 2</td>
</>
);
}
}

We can use the fragment in iterating of list as well.

Change state of a child component from its parent.

source: Source: https://www.freecodecamp.org/news/react-changing-state-of-child-component-from-parent-8ab547436271/

Pass Data from Child to Parent

  • Child to Parent — Use a callback and states

If I have data in my child that my parent needs access to, I can do the following:

  • Define a callback in my parent which takes the data I need in as a parameter.
  • Pass that callback as a prop to the child (see above).
  • Call the callback using this.props.[callback] from the child (insert your own name where it says [callback] of course), and pass in the data as the argument.

Why pass Props to super()

class MyComponent extends React.Component {
constructor() {
console.log(this); // Reference Error
}
render() {
return <div>Hello {this.props.name}</div>;}
}

In contrast:
class MyComponent extends React.Component {
constructor() {
super();
console.log(this); // this logged to console
}
render() {
return <div>Hello {this.props.name}</div>;}
}

You may see examples of components created by extending the React.Component class that do not call super() but you’ll notice these don’t have a constructor as well, hence why it is not necessary.

class MyOtherComponent extends React.Component {
render() {
return <div>Hi {this.props.name}</div>;
}
}

◉ Why Middle-wares ?

What is a curried function? A curried function is a function that returns another function.

Currying Example

By default, we cannot handle current scenarios simply using reducer, as reducer is designed to run synchronous code only. So ,we need something where we can catch the action in middle, do our operation ( of saving etc.) and once it is done, proceed with that action to the reducer to update the state.

The middleware sits in between the dispatch and reducers, which means we can alter our dispatched actions before they get to the reducers or execute some code during the dispatch.

An example of a redux middleware is redux-thunk which allows you to write action creators that return a function instead of an action.

const customMiddleware = store => next => action => {
...
}

Therefore we can say our middleware receives a store, then returns a function that receives a next function and returns another function that receives an action.

◉ Handle events using arrow functions

Popular convention in React is to name handler method similar as

handleChange() {…}

when your component looks similar as

render() {
return(<MyInput onChange={...} />
}

and you want to handle onChange callback. Now all what you need is to pass your method into onChange property. Simply

onChange={ this.handleChange }

won’t work because you need to bind `this` value from function to our class (each function creates own environment).

We could use some tricks, as assignment that = this or use lodash method _.bind(), but thankfully most of browser support native .bind() method.

So finally your code should look like this:

render() {
return(<MyInput onChange={ this.handleChange.bind(this) } />
}

Binding methods in property is anti-pattern. Why ?

  • This will cause the render() function to create a new function on every render.
  • It works, so everything should be fine, but what will happen if you would like to use handleChange method in another components in the same class?
render() {
return(
<MyInput onChange={ this.handleChange.bind(this) } />.
<MyAnotherInput onChange={ this.handleChange.bind(this) } />
)
}

Not really cool, because you need to add binding twice.

Thanks to ES6 class notation we have solution for this problem. A much better way of doing the same is we can bind our event handlers in class constructor.

Here, event passed in React is synthetic and cross browser compatible. A method in ES6 can be an event handler. In JavaScript classes, methods are not bound to class by default. These methods in class should be declared in constructor with binding as shown below −

class MyClass extends Component {
constructor(props) {
super(props)
this.handleChange = this.handleChange.bind(this)
}
}

As you have probably seen, when we create event handler method, we always need to add this to constructor, to bind `this`. Quite tiresome.

To be honest, there is no sense to create constructor method only for binding your methods. There should be another solution, and there is.

[2]. Or we can use arrow functions which will bind the methods automatically and then no need to add bind in constructor.

adduser = () => {}

[3]. If we are not using arrow functions , another alternative is to call the method and binding on React element itself −

addUser(){}<button onClick={ (e)=>{this.addUser(e)}}>
Add User
</button>

We have created new anonymous function, which automatically bind this, that’s why we don’t need to use .bind() method. However, the problem with above anonymous callback function is , it will be created every time button renders on the screen and it can affect performance.

This is still not perfect solution, because we need to update parameters in arrow function wrappers and we create new instances each time when render method is triggered. Arrow functions in React properties are also NOT great idea.

Arrow function as method is the Recommended one

What we need to do, is to instead of standard method notation

handleChange(e) {…}

use arrow function expression.:

handleChange = (e) => {…}

Partial application with arrow functions

Finally we don’t need to use .bind() method at all. We use arrow functions, so we can pass handler in this way:

<MyInput onKeyPress={ (e) => handleKeyPress(item, e) } />

Creating arrow function in JSX property is NOT good pattern, so instead we can use similar pattern as mentioned before and return function by another function. Thanks to arrow functions it takes us less effort:

handleKeyPress = (item) => (e) => {…}

When we run handleKeyPress(item) method, we get new anonymous function, which first parameter is e, and which has reference to item from parent function scope.

import React, { Component } from "react";
import { MyInput } from "myInputs";
class MyComponent extends Component {handleKeyPress = (item) => (e) => {
e.preventDefault();
if (e.nativeEvent.keyCode === 13) {
console.log(`This is enter on item, which is called
${item}!`);
}
};

renderItem(item) {
return <MyInput onKeyPress={this.handleKeyPress(item)} />;
}

render() {
const items = ["Item1", "Item2", "Item3"];
return
<div>
{items.map(this.renderItem)}
</div>;
}
}

Now we don’t need to bind methods. We also don’t need to create new function in JSX property, so code should be valid with ESLint.

If you send arguments without using the bind method, (this.love(this, "God") instead of this.love.bind(this, "God")), the shoot function will be executed when the page is loaded instead of waiting for the button to be clicked.

In both cases, (with & w/o bind), the “e” argument representing the React event will be passed as a 2nd argument after the “item”.

With an arrow function (=>), we have to pass it (e) EXPLICITLY, but with bind, any further arguments are automatically forwarded as in below:

event handling using arrow function

Without arrow function (meaning with the .bind method), the React event object is sent automatically (implicitly) as the last argument when using the bind() method:

event handling using .bind(this, “goal”)

Static context vs. dynamic context

If you bind normal function, you can rebind it later, so the context is dynamic.

In case of arrow function you cannot change “this” context, it’s static.

◉ require vs (import and export)

In vanilla JavaScript, you have to first tell the browser that you’re using modules. You do that by putting a module script with type=”module” in the head tag of your HTML.

<script type=”module” src=”fileName.js”></script>

Let’s say for example you want to import a function from a JavaScript file called index.js to another file called app.js . To do that, you have to export the function first and then import it.

Here is an example:

Exporting:

export const multiply = (a, b) => {
return x * y;
}

Importing:

import { multiply } from ‘./index.js’;

That’s it, now you can use the function multiply in the file app.js .

source: https://medium.com/@thejasonfile/a-simple-intro-to-javascript-imports-and-exports-389dd53c3fac

ES5 Example

ES6 example

Instead of ‘require’ you now use ‘import’ and you can also have an ‘export default’ statement if you only have one thing to export out of a file.

source: https://medium.com/@trekinbami/a-not-so-in-depth-explanation-of-es6-modules-import-and-export-13a80300f2f0

Exporting

export function sayName(name) {
console.log(`Hello ${name}`);
}
export function sayAnimal(animal) {
console.log(`What animal? ${animal}`);
}
export default function whatsYourFlava(flava) {
console.log(`I'm liking ${flava}?`);
}

We’ll call this file Helpers.js. Remember: when using export, the only thing we’re saying is: “Make this piece of code available outside this module”.

The first two are named exports. When importing a named export, you’ll need to specifically import your export by name. So in this case: sayName and sayAnimal. The third one is a default export. This is the piece of code that will get imported from the module, when you don’t specify a certain name of a certain piece of code. That’s why the smart folks at the javascript company named it a export default.

Importing

import { sayName, sayAnimal } from './Helpers';
import whatsYourFlava from './Helpers';
sayName('Sam');
//Hello Sam
sayAnimal('Giraffe');
//What animal? Giraffe
whatsYourFlava('grapes');
//I'm liking grapes

When importing named exports, you’ll have to wrap them in curly braces. If you’re importing multiple exports from the same module, you can concatenate them, comma based, and use them in the same wrapping curly braces. This looks a lot like destructuring in ES6, but actually doesn’t have anything to do with it. Just so you know.. you know.

When you import, and omit the curly braces, it will look for the default export in the module you’re importing from. Because it knows it has to look for the default export, you can use any random name for your import. This will work too:

import bruhGetMoney from './Helpers';
bruhGetMoney('money');
//I'm liking money

◉ Benefits of Server Side Rendering Over CSR

We are using server side rendering for two reasons:

  • Performance benefit for our customers
  • Consistent SEO performance

The main difference is that for SSR your server’s response to the browser is the HTML of your page that is ready to be rendered, while for CSR the browser gets a pretty empty document with links to your javascript. That means your browser will start rendering the HTML from your server without having to wait for all the JavaScript to be downloaded and executed. In both cases, React will need to be downloaded and go through the same process of building a virtual dom and attaching events to make the page interactive — but for SSR, the user can start viewing the page while all of that is happening. For the CSR world, you need to wait for all of the above to happen and then have the virtual dom moved to the browser dom for the page to be viewable.

Another Bonus: The blank page flicker that happens with CSR also doesn’t really happen with SSR — though most people avoid it by having a loading image sent down in the server response which is removed when everything is done loading.

Now, there are a few caveats:

  • While the page is rendered earlier and the customer can see the page sooner, they can’t really interact with it until react is done executing. If the customer is really fast and clicks a button, the action won’t be executed until React is done executing;
  • SSR TTFB(Time To First Byte)is slower than CSR, because your server will have to spend the time to create the HTML for your page instead of just sending out a relatively empty response;
  • SSR throughput of your server is significantly less than CSR throughput. For react in particular, the throughput impact is extremely large. ReactDOMServer.renderToString is a synchronous CPU bound call, which holds the event loop, which means the server will not be able to process any other request till ReactDOMServer.renderToString completes. Let’s say that it takes you 500ms to SSR your page, that means you can at most do at most 2 requests per second. *BIG CONSIDERATION*

source: https://medium.com/vue-mastery/10-reasons-to-use-nuxt-js-for-your-next-web-application-522397c9366b

There are a lot of advantages to having a SPA over a traditional website. For example, you can build very snappy UIs that update fast. But SPAs also come with disadvantages such as long load times, and Google struggles with them because there’s no content initially on the page to crawl for SEO purposes. All of the content is generated with JavaScript after the fact.

Access the Redux Store Outside a React Component

https://daveceddia.com/access-redux-store-outside-react/#:~:text=If%20you%20need%20to%20dispatch,via%20react%2Dredux's%20connect%20function

◉ Error handling in React 16

1. <React.StrictMode>

StrictMode checks are done in development mode only and will NOT affect your production build.

  • React’s StrictMode is sort of a helper component that will help you write better react components, you can wrap a set of components with <StrictMode /> and it’ll basically: Verify that the components inside are following some of the recommended practices and warn you if not in the console.

If you see warnings in StrictMode, you will likely encounter bugs when trying to use Concurrent React.

Like Fragment, StrictMode does not render any UI, it only activates checks and adds warnings at runtime.

How to use it?

Right after doing that you’ll be able to see warnings in your developer tools console.
At the moment, StrictMode helps with a few specific issues, we’ll cover them up and see how the warnings look like.

2. Error boundary in React.js

Create a react class component

import React, {Component} from 'react';
class ErrorBoundary extends Component{
state={
isErrorOccured:false,
errorMessage:''
}
componentDidCatch=(error,info)=>{
this.setState({isErrorOccured:true,errorMessage:error});
}
render(){
if(this.state.isErrorOccured){
return <p>Something went wrong</p>
}else{
return <div>{this.props.children}</div>
}
}
}
export default ErrorBoundary;

We have used a React life cycle method componentDidCatch which receives two arguments error and info related to it.

componentDidCatch=(error,info)=>{
this.setState({isErrorOccured:true, errorMessage:error});
}

How to use error boundary

<ErrorBoundary>
<User/>
</ErrorBoundary>

We are wrapping the child component where there is possibility of error occurring inside error boundary like above.

Please note that this error boundary approach only works in production mode of build. In development mode, it simply displays the actual error on browser instead of these custom errors.

Use of Error Boundary on production helps to show user meaningful error message on screen instead of displaying some technical code errors.

If you have built a React app at any point in your programming career, you probably have experienced an error at some point that was cryptic and did not provide any meaningful context on what actually happened.

That meant error occurred at some point in the application and our React component did not handle the error gracefully.

A JavaScript error in a part of the UI shouldn’t break the whole app. To solve this problem for React users, React 16 introduces a new concept of an “error boundary”.

try/catch only works for imperative code, but React components are declarative.

Since early React development (≤15), it was common for a child component throwing an error to break the entire application and React did not provide a way to handle them gracefully in components. That’s why Error Boundaries are a good thing.

Error boundaries catch errors during rendering, in lifecycle methods, and in constructors of the whole tree below them.

In React 16 we have a built-in function called componentDidCatch to deal with this uncaught errors. Let’s take a look:

Error Boundaries in React

🧐 First all, important to know that Error Boundaries will not catch errors in:

  1. Event handlers. ** — Use a try / catch block instead within event handlers.
  2. Asynchronous code (e.g. setTimeout or requestAnimationFrame callbacks)
  3. Server side rendering
  4. Errors within the Error Boundary Component. — You cannot save others if you cannot save yourself first.

After that, let’s recall a new lifecycle method called

componentDidCatch(error, info)

😀 It works in the same way that Javascript’s try/catch works.

With error boundaries, even if one of your component’s results in an error, the entire react app would not get unmounted and instead only the erroneous component would display a fallback UI and the entire app would still be fully functional.

Experience with Front-end Technologies and MERN / MEAN Stack. Working on all Major UI Frameworks like React, Angular.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store