ReactJS – a quick walk through

react logo

ReactJS is a JavaScript library for building high performance and interactive user interfaces for web apps. It is component based – which means, all you have to do in order to develop UI in React is to create and use (and reuse) custom components. In built components are <div>, <button> etc., and custom component can be anything in an app such as a <list of users/>. This <list of users/> component can further contain a list of child components named <user/>. The <list of users/> can itself be a child of some another component named <active users/>. Here DOM tree will look like:

<active users> 
-<list of users> 
--<user/>
--<user/>
--<user/>
-</list of users>
</active users>

Note that, in order to make rich and complex UIs in React while keeping the code maintainable and scalable, one must need to make sure that the components are small, and are responsible for doing only one thing. For example, a user component should only display the user data. It should not be concerned with how the data is received (whether through an API or reading from file using promise or observable etc.,). Such tasks can be carried out by another component such as <get users/> which is only responsible to receive users data and once data is received, it can be passed to <user/> component to display it on the screen.

Visit this page for better understanding: https://reactjs.org/docs/thinking-in-react.html

Each React component is encapsulated and can operate independently; this allows you to build complex UIs from simple components.

Functional and class components

Technically, a component can either be a function or a class. The major difference between functional and class components is, class component can maintain their state (and its children’s as well) while functional component cannot.

props

Passing props is how information flows in React apps, from parents to children. props is an object of properties of a component. For example,

<listOfUsers selectUser={this.selectItem} />

in above <listOfUsers/> component, selectUser is a property added to this component which can be accessed from props object as: props.selectUser.

A functional component takes in parameter, called props (short for “properties”), and returns a hierarchy of views to display via the render method. In simple words, functional components are a simpler way to write components that only contain a render method and don’t have their own state. Instead of defining a class which extends React.Component, we can write a function that takes props as input and returns what should be rendered.

Class component also gets props object as their property, hence, in class component, props can be accessed as this.props.selectUser.

render()

The render method returns a description of what you want to see on the screen. React takes the description and displays the result. In particular, render returns a React element, which is a lightweight description of what to render. Most React developers use a special syntax called “JSX” which makes these structures easier to write. The  <div /> syntax is transformed at build time to React.createElement('div').

JSX

JSX comes with the full power of JavaScript. You can put any JavaScript expressions within braces inside JSX. Each React element is a JavaScript object that you can store in a variable or pass around in your program.

Separation of concerns with JSX

TBD

State

To “remember” things, components use state.

React components can have state by setting this.state in their constructors. this.state should be considered as private to a React component that it’s defined in.

When you call setState in a component, React automatically updates the child components inside of it too.

To collect data from multiple children, or to have two child components communicate with each other, you need to declare the shared state in their parent component instead. The parent component can pass the state back down to the children by using props; this keeps the child components in sync with each other and with the parent component.

Controlled components

Components whose state is maintained by their parent are called controlled components.

How React is a declarative library?

TBD

Immutability: why is it important?

TBD

Features of React components

Reusable – same component can be used at different places.

Composable – components can be combined with other components to build sophisticated interfaces (more complex components).

Unit testable – since a component is an independent function, it is easy to unit test them.

How to structure React components?

As such there are no rules about how to structure component tree.  In the initial stage of a project, the picture about how the component hierarchy will eventually look like is often unknown, therefore, it is better to start with what makes sense and later on refactor or remove the component if required. Many people start from bottom to up in the tree but sometimes it is useful to start with the top most one if we already know the tree structure. Further, test your code as often as you can. For example, rather than testing a fully integrated component, put some placeholder text and check whether it is rendering correctly on the browser.

Thinking in React is very useful article on this topic from React docs.

How react updates the DOM?

(From https://www.slideshare.net/floydophone/react-preso-v2 slide 62)

  • React builds a new virtual DOM subtree
  • … diffs it with the old one
  • … computes a minimal set of DOM mutations and puts them in a queue
  • … and batch executes all updates

Why the virtual DOM is so fast and optimized?

(From https://www.slideshare.net/floydophone/react-preso-v2 slide 57)

  • Computes minimal DOM operations
  • Batched reads and writes for optimal DOM performance
  • Because the DOM is slow

In addition to this, React comes with optimization hooks that can be used to tell react not to “diff” a certain portion of tree.

Important points to remember

Every react event function receives an “event” object as an argument. This event object is a wrapper around native JavaScript event object. All the methods available on native object are available on this argument.

To re-render a component, we have to place something into the state and modify it with an action.

For a component to access the state of its parent component, the parent has to pass the state to child as property.

Just like we use ngFor* in Angular, to create elements in HTML from an array or an object, use .map method.

When your state update operation depends on the state itself, use prevState argument of setState to avoid the race condition.

onClick handler needs a function reference, not a function call.

Configuring an Angular app with a CSS preprocessor

While setting up an Angular project, if we want to use some CSS preprocessor like SCSS or LESS, it would be a great idea if every time while generating a new component the preprocessor file get generated instead of plain CSS. We can do with `–style’ option as follows:

ng new newApp --style=less

For an existing application, we can make the following changes in the “defaults” object in .angular-cli.json in order to achieve this configuration.

"defaults": {
"styleExt": "less",
"component": {}
}

Principles of Redux

This post is a high level summary of some of the videos of Dan Abramov’s course, Getting started with Redux. Dan is Co-Author of Redux and React core team member.

Redux has three principles as following:

First principle says, Everything changing in the UI whether it is data or state of UI components is stored in a single JavaScript plain object called state or state tree.

According to second principle, State is read only or can say, immutable. This helps in keep the track of history of how state was modified. Anytime we need to change the state, we have to dispatch an action. Just like state is the minimal representation of data in the app, an action is the minimal representation of  change in that data. Action is a plain JS object with mandatory type property. With type property, we can differentiate among different kind of actions. Components do not know anything about actions do to update state and so on. They only know they need to dispatch an action with type and payload.  

The third and last principle of Redux is that in order to describe state mutations, you have to write a function that takes previous state, the action being dispatched and returns the next state of the app and this function has to be pure. Pure functions are those whose return value depends solely on their arguments. They always return same results when invoked with a set of arguments. Therefore, they are predictable. Such a pure function which describes mutations in the app state is called reducer function in Redux. 

Reducer accepts state and action as arguments and returns the next state. According to a convention in Redux, if the state argument is passed as undefined, reducer must return the initial state of the app. 

Store

Store holds all the three principles of Redux together i.e. it holds the state object, it dispatches an action (to update the state) and at the time of creating it, we need to specify reducer which tells how state is updated with actions.

Store has three important methods:

getState(): It retrieves the current state of Redux store. 

dispatch(): It dispatches an action to update the state of the application.

subscribe(): It registers a callback which runs anytime an action updates th store.

Reducer composition pattern

Just like complex components can be composed with the help of multiple child components each having different responsibility, reducers (which are pure JavaScript functions) can also be (and should be) composed of child reducers which are responsible for updating different parts of the state. Therefore, as per this pattern, multiple child reducers exists in our app responsible for updating different parts of the state. Later on, we create a new reducer that calls the existing reducers to manage parts of its state and combines the results in a single state object. This pattern helps scale Redux development because different people can work on different reducers handling the same actions without conflicting each other. 

Reference: https://egghead.io/lessons/react-redux-reducer-composition-with-objects

Example TODO app:

Presentational components

Components which are “dumb”, concerned about the “looks”, i.e., how the things render and do not know anything about their behaviour and from where the data is coming from are called presentational components.

Container components

A container component connects presentational component to a Redux store and specify data and behaviour that it needs. When props are being passed several levels down the state tree, it is advisable to extract container components so that we don’t have to pass the props to “intermediate” components which just pass them to their children and don’t actually need for themselves. Container components are usually class components because they will not receive any data (props) from parent components and therefore, need to maintain their own internal state data. Since, their render method needs state data, they subscribe to store updates in component lifecycle methods (componentDidMount and componentWillUnmount for unsubscribe). Every time the store updates, they call forceUpdate method.

Why and when separating out components as presentational and container components is a good idea?

As the Redux author Dan Abramov suggests, separating the container and the presentional components is often a good idea but it is not necessary to do this every time. Only do this when it truly reduces the complexity of the code base. First try to extract presentational components and if there is too much boilerplate passing the props to them, then we can create the containers around them that load the data and specify the behaviour.

Rendering a list of items in React

Usually, in order to render a list of items in React, create a separate component to render particular item and then use .map, for or forEach loop and push the component (with props) into an array. This array then iterated over by React when used in JSX. In the following example, components ProductRow and ProductCategoryRow are being pushed into an array row which is when used in JSX as {row}  is looped over automatically by React and items are rendered as a list in the browser.  

const ProductRow = (props) => {
return (
<tr>
<td style={{color: props.product.stocked === true ? '' : 'red'}}>
{props.product.name}
</td>
<td>{props.product.price}</td>
</tr>
)
}
const ProductCategoryRow = (props) => {
return (
<tr>
<th colSpan="2">{props.category}</th>
</tr>
)
}
const SearchBar = () => {
return (
<div>
<div><input className="search" type="text" placeholder="Search…"></input></div>
<div><input className="checkbox" type="checkbox"></input>Only show products in stock</div>
</div>
)
}
const ProductTable = (props) => {
let rows = [];
let lastCategory = null;
props.tableData.forEach(product => {
if(product.category !== lastCategory) {
rows.push(
<ProductCategoryRow
category={product.category}
key={product.category} />
);
}
rows.push(
<ProductRow
product={product}
price={product.price}
key={product.name}/>
);
lastCategory = product.category;
});
return (
<table>
<thead>
<tr>
<th>Name</th>
<th>Price</th>
</tr>
</thead>
<tbody>
{rows}
</tbody>
</table>
)
}