Concepts of React JS — Part 2

Image for post
Image for post

📄 Table of Contents

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

◉ setState()

  • setState() is Asynchronous in nature.
  • 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 it will reflect correctly in render() method.
Image for post
Image for post

why to use setState()

You should never set the state directly like this:

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.

◉ React Fragment

Most of the times we need to return multiple elements from a component. React Fragment helps in returning multiple elements. The other alternative is to use a html element like div to wrap them. But using extra html node can cause some semantic issues.

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.

◉ Why Middle-wares ?

Middleware(s) are (curried) functions.

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

Image for post
Image for post
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

source: source: https://medium.com/silesis/handle-events-in-react-with-arrow-functions-ede88184bbb

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.

Image for post
Image for post

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.

Image for post
Image for post

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:

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)

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

Image for post
Image for post

ES5 Example

Using ES5 syntax in Node means that the sharing of code between files is done with the ‘require’ and ‘module.exports’ statements. A ‘module’ in Javascript can be thought of as a container that holds related code which can then be exported to another file.

ES6 example

If you are using the ES6 then the idea of imports and exports is the same but the syntax is a bit different

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

Let’s pretend we’re writing a module full of helper functions and we want to use those helper functions in multiple other modules. In order to use certain pieces of code from a module in other files/modules, we have to.. export it.

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

Let’s import those amazing helpful helper functions:

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

source:https://medium.com/walmartlabs/the-benefits-of-server-side-rendering-over-client-side-rendering-5d07ff2cefe8

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

Read at

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

Error boundary in React.js

The error boundary mechanism helps to show CUSTOM meaningful error message to user on production instead of showing any programming language error.

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.

<React.StrictMode>

  • React StrictMode is a feature added in version 16.3 and aimed to help us in finding potential problems in an application.

* 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?

All you need to do in order to enable StrictMode (from version 16.3) is to wrap the part you want in your app with <React.StrictMode>.
You can wrap the whole app or only specific nodes.
Here’s an example of wrapping the whole app:

Image for post
Image for post

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.

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