Core React
React (aka React.js or ReactJS) is an open-source front-end JavaScript library that is used for building composable user interfaces, especially for single-page applications. It is used for handling view layer for web and mobile apps based on components in a declarative approach.
React was created by Jordan Walke, a software engineer working for Facebook. React was first deployed on Facebook's News Feed in 2011 and on Instagram in 2012.
The main principle of this extension was to make front-end code easier to understand and to help avoid cross-site scripting attacks. The project was successful to prevent the malicious content submitted by the scrubbing user.
But there was a different problem with XHP in which dynamic web applications require many roundtrips to the server, and XHP did not solve this problem. Also, the whole UI was re-rendered for small change in the application. Later, the initial prototype of React is created with the name FaxJ by Jordan inspired from XHP. Finally after sometime React has been introduced as a new library into JavaScript world.
Note: JSX comes from the idea of XHP
The major features of React are:
- Uses JSX syntax, a syntax extension of JS that allows developers to write HTML in their JS code.
- It uses Virtual DOM instead of Real DOM considering that Real DOM manipulations are expensive.
- Supports server-side rendering which is useful for Search Engine Optimizations(SEO).
- Follows Unidirectional or one-way data flow or data binding.
- Uses reusable/composable UI components to develop the view.
React Router
React Router is a powerful routing library built on top of React that helps you add new screens and flows to your application incredibly quickly, all while keeping the URL in sync with what's being displayed on the page.
React Router is a wrapper around the history library which handles interaction with the browser's window.history with its browser and hash histories. It also provides memory history which is useful for environments that don't have global history, such as mobile app development (React Native) and unit testing with Node.
React Router v4 provides below 3
The above components will create browser, hash, and memory history instances. React Router v4 makes the properties and methods of the history instance associated with your router available through the context in the router object.
React Internationalization
The React Intl library makes internationalization in React straightforward, with off-the-shelf components and an API that can handle everything from formatting strings, dates, and numbers, to pluralization. React Intl is part of FormatJS which provides bindings to React via its components and API.
Below are the main features of React Intl,
- Display numbers with separators.
- Display dates and times correctly.
- Display dates relative to "now".
- Pluralize labels in strings.
- Support for 150+ languages.
- Runs in the browser and Node.
- Built on standards.
The library provides two ways to format strings, numbers, and dates:
- Using react components:
harmony <FormattedMessage > </FormattedMessage>
- Using an API:
const messages = defineMessages({
accountMessage: {
id: "account",
defaultMessage: "The amount is less than minimum balance.",
},
});
formatMessage(messages.accountMessage);
React Testing
For example, if you have the following component:
function MyComponent() {
return (
<div >
<span >{"Title"}</span>
<span >{"Description"}</span>
</div>
);
}
Then you can assert as follows:
harmony
import ShallowRenderer from "react-test-renderer/shallow";
// in your test
const renderer = new ShallowRenderer();
renderer.render(<MyComponent >);
const result = renderer.getRenderOutput();
expect(result.type).toBe("div");
expect(result.props.children).toEqual([
<span >{"Title"}</span>,
<span >{"Description"}</span>,
]);
</MyComponent>
This package provides a renderer that can be used to render components to pure JavaScript objects, without depending on the DOM or a native mobile environment. This package makes it easy to grab a snapshot of the platform view hierarchy (similar to a DOM tree) rendered by a ReactDOM or React Native without using a browser or jsdom.
harmony
import TestRenderer from "react-test-renderer";
const Link = ({ page, children }) => <a >{children}</a>;
const testRenderer = TestRenderer.create(
<Link >{"Facebook"}</Link>
);
console.log(testRenderer.toJSON());
// {
// type: 'a',
// props: { href: 'https://www.facebook.com/' },
// children: [ 'Facebook' ]
// }
React Redux
The workflow between dispatcher, stores and views components with distinct inputs and outputs as follows:
Redux follows three fundamental principles:
- Single source of truth: The state of your whole application is stored in an object tree within a single store. The single state tree makes it easier to keep track of changes over time and debug or inspect the application.
- State is read-only: The only way to change the state is to emit an action, an object describing what happened. This ensures that neither the views nor the network callbacks will ever write directly to the state.
- Changes are made with pure functions: To specify how the state tree is transformed by actions, you write reducers. Reducers are just pure functions that take the previous state and an action as parameters, and return the next state.
React Native
React Native is a mobile framework that compiles to native app components, allowing you to build native mobile applications (iOS, Android, and Windows) in JavaScript that allows you to use React to build your components, and implements React under the hood.
React Native can be tested only in mobile simulators like iOS and Android. You can run the app in your mobile using expo app (https://expo.io) Where it syncs using QR code, your mobile and computer should be in same wireless network.
You can use console.log, console.warn, etc. As of React Native v0.29 you can simply run the following to see logs in the console:
$ react-native log-ios
$ react-native log-android
React supported libraries & Integration
Reselect keeps a copy of the last inputs/outputs of the last call, and recomputes the result only if one of the inputs changes. If the the same inputs are provided twice in a row, Reselect returns the cached output. It's memoization and cache are fully customizable.
Flow is a static analysis tool (static checker) which uses a superset of the language, allowing you to add type annotations to all of your code and catch an entire class of bugs at compile time.
PropTypes is a basic type checker (runtime checker) which has been patched onto React. It can't check anything other than the types of the props being passed to a given component. If you want more flexible typechecking for your entire project Flow/TypeScript are appropriate choices.
Miscellaneous
Let's see the main features of Reselect library,
- Selectors can compute derived data, allowing Redux to store the minimal possible state.
- Selectors are efficient. A selector is not recomputed unless one of its arguments changes.
- Selectors are composable. They can be used as input to other selectors.
- #### Give an example of Reselect usage?
Let's take calculations and different amounts of a shipment order with the simplified usage of Reselect:
import { createSelector } from "reselect";
const shopItemsSelector = (state) => state.shop.items;
const taxPercentSelector = (state) => state.shop.taxPercent;
const subtotalSelector = createSelector(shopItemsSelector, (items) =>
items.reduce((acc, item) => acc + item.value, 0)
);
const taxSelector = createSelector(
subtotalSelector,
taxPercentSelector,
(subtotal, taxPercent) => subtotal * (taxPercent / 100)
);
export const totalSelector = createSelector(
subtotalSelector,
taxSelector,
(subtotal, tax) => ({ total: subtotal + tax })
);
let exampleState = {
shop: {
taxPercent: 8,
items: [
{ name: "apple", value: 1.2 },
{ name: "orange", value: 0.95 },
],
},
};
console.log(subtotalSelector(exampleState)); // 2.15
console.log(taxSelector(exampleState)); // 0.172
console.log(totalSelector(exampleState)); // { total: 2.322 }
Redux can be used as a data store for any UI layer. The most common usage is with React and React Native, but there are bindings available for Angular, Angular 2, Vue, Mithril, and more. Redux simply provides a subscription mechanism which can be used by any other code.
Redux is originally written in ES6 and transpiled for production into ES5 with Webpack and Babel. You should be able to use it regardless of your JavaScript build process. Redux also offers a UMD build that can be used directly without any build process at all.
Old Q&A
If you try to update the state directly then it won't re-render the component.
//Wrong
this.state.message = "Hello world";
Instead use setState() method. It schedules an update to a component's state object. When state changes, the component responds by re-rendering.
//Correct
this.setState({ message: "Hello World" });
Note: You can directly assign to the state object either in constructor or using latest javascript's class field declaration syntax.
The callback function is invoked when setState finished and the component gets rendered. Since setState() is asynchronous the callback function is used for any post action.
Note: It is recommended to use lifecycle method rather than this callback function.
setState({ name: "John" }, () =>
console.log("The name has updated and component re-rendered")
);
There are 3 possible ways to achieve this in class components:
- Binding in Constructor: In JavaScript classes, the methods are not bound by default. The same rule applies for React event handlers defined as class methods. Normally we bind them in constructor.
class User extends Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
console.log("SingOut triggered");
}
render() {
return <button >SingOut</button>;
}
}
- Public class fields syntax: If you don't like to use bind approach then public class fields syntax can be used to correctly bind callbacks. The Create React App enables this syntax by default.
harmony
handleClick = () => {
console.log("SingOut triggered", this);
};
harmony
<button >SingOut</button>
- Arrow functions in callbacks: It is possible to use arrow functions directly in the callbacks.
harmony
handleClick() {
console.log('SingOut triggered');
}
render() {
return <button > this.handleClick()}>SignOut</button>;
}
Note: If the callback is passed as prop to child components, those components might do an extra re-rendering. In those cases, it is preferred to go with .bind() or public class fields syntax approach considering performance.