Abstract: The questions are very detailed and the illustrations are very nice.
- Here’s all the React interview information you need
- Author: front-end small wisdom
FundebugReprinted with authorization, the copyright belongs to the original author.
React is one of the popular javascript frameworks that will become even more popular in 2019 and beyond. React was first released in 2013 and has been hugely popular over the years. It is a declarative, component-based, and efficient javascript library for building user interfaces.
Here are the topics you must know before your interview.
- What is declarative programming
- Declarative vs. imperative programming
- What is functional programming
- What is a component design pattern
- What’s the React
- What’s the difference between React and Angular
- What is the virtual DOM and how it works
- What is the JSX
- Components and different types
- Props and State
- What is a PropTypes
- How to update status and not update status
- Component lifecycle approach
- Beyond the combination of inheritance
- How do I apply styles in React
- What is Redux and how it works
- What is the React router and how it works
- What is an error boundary
- What is the Fragments could
- What is a Portal?
- What is the Context
- What is the Hooks
- How to improve performance
- How do I preserve the data when the page is reloaded
- How do I call an API from React
- conclusion
What is declarative programming
Declarative programming is a programming paradigm that focuses on what you’re going to do, not how you’re going to do it. It expresses logic without explicitly defining steps. This means that we need to declare the components to be displayed based on a logical calculation. It does not describe the control flow steps. Examples of declarative programming are HTML, SQL, and so on
HTML file
// HTML
<div>
<p>Declarative Programming</p>
</div>
Copy the code
SQL file
select * from studens where firstName = 'declarative';
Copy the code
Declarative vs. imperative programming
Declarative programming is written in a way that describes what should be done, while imperative programming describes how. In declarative programming, let the compiler decide how to do things. Declarative programs are easy to reason about because the code itself describes what it is doing.
Here’s an example where we multiply each element in an array by 2, and we use the declarative map function to let the compiler do the rest, while using imperative requires writing all the process steps.
const numbers = [1.2.3.4.5];
/ / the declarative
const doubleWithDec = numbers.map(number= > number * 2);
console.log(doubleWithDec)
/ / imperative
const doubleWithImp = [];
for(let i=0; i<numbers.length; i++) {
const numberdouble = numbers[i] * 2;
doubleWithImp.push(numberdouble)
}
console.log(doubleWithImp)
Copy the code
What is functional programming
Functional programming is part of declarative programming. Functions in javascript are first class citizens, which means that functions are data that you can save, retrieve, and pass around in your application like variables.
Functional programming has some core concepts, such as:
- Immutability
- Pure Functions
- Data translations
- Higher-Order Functions
- recursive
- combination
Immutability
Immutable means immutable. In functional programming, you can’t change the data, and you can’t. If you want to change or change the data, you must copy the data copy changes.
For example, here is a student object and a changeName function. If you want to change the student’s name, you need to copy the student object and then return the new object.
In javascript, function arguments are references to actual data. You shouldn’t use student.firstName = “testing11”, which changes the actual student Object.
let student = {
firstName: "testing".lastName: "testing".marks: 500
}
function changeName(student) {
// student.firstName = "testing11" //should not do it
let copiedStudent = Object.assign({}, student);
copiedStudent.firstName = "testing11";
return copiedStudent;
}
console.log(changeName(student));
console.log(student);
Copy the code
Pure functions
A pure function is a function that always takes one or more arguments, evaluates them, and returns data or a function. It has no side effects, such as setting global state, changing application state, and it always treats parameters as immutable data.
I want to add an address to the Student object using the appendAddress function. If you use an impile function, which has no arguments, change the Student object directly to change the global state.
Using a pure function, it takes arguments, calculates based on the arguments, and returns a new object without modifying the arguments.
let student = {
firstName: "testing".lastName: "testing".marks: 500
}
// Impure function
function appendAddress() {
student.address = {streetNumber:"0000".streetName: "first".city:"somecity"};
}
console.log(appendAddress());
/ / pure functions
function appendAddress(student) {
let copystudent = Object.assign({}, student);
copystudent.address = {streetNumber:"0000".streetName: "first".city:"somecity"};
return copystudent;
}
console.log(appendAddress(student));
console.log(student);
Copy the code
Data conversion
We talked a lot about immutability, how we can change data if it’s immutable. As mentioned above, we always make a transformed copy of the original data, rather than directly changing the original data.
A few more javascript built-in functions, of course there are many others, but here are some examples. All of these functions do not change existing data, but instead return a new array or object.
let cities = ["irving"."lowell"."houston"];
// we can get the comma separated list
console.log(cities.join(', '))
// irving,lowell,houston
// if we want to get cities start with i
const citiesI = cities.filter(city= > city[0= = ="i");
console.log(citiesI)
// [ 'irving' ]
// if we want to capitalize all the cities
const citiesC = cities.map(city= > city.toUpperCase());
console.log(citiesC)
// [ 'IRVING', 'LOWELL', 'HOUSTON' ]
Copy the code
Higher-order functions
Higher-order functions are functions that take a function as an argument or return function, or sometimes both. These higher-order functions can manipulate other functions.
Array.map, array. filter, and array. reduce are high-order functions because they take functions as arguments.
Const numbers = [10,20,40,50,60,70,80] const out1 = number. map(num => num * 100); console.log(out1); // [ 1000, 2000, 4000, 5000, 6000, 7000, 8000 ] const out2 = numbers.filter(num => num > 50); console.log(out2); // [ 60, 70, 80 ] const out3 = numbers.reduce((out,num) => out + num); console.log(out3); / / 330Copy the code
Here is another example of a higher-order function called isPersonOld, which accepts two other functions, Message and isYoung.
const isYoung = age= > age < 25;
const message = msg= > "He is "+ msg;
function isPersonOld(age, isYoung, message) {
constreturnMessage = isYoung(age)? message("young"):message("old");
return returnMessage;
}
// passing functions as an arguments
console.log(isPersonOld(13,isYoung,message))
// He is young
Copy the code
recursive
Recursion is a technique in which a function calls itself until certain conditions are met. It is best to use recursion rather than loop whenever possible. You have to be aware that browsers can’t handle too much recursion and throw errors.
Here is an example of a recursion in which you print a name that looks like a staircase. We could also use a for loop, but we prefer recursion whenever possible.
function printMyName(name, count) {
if(count <= name.length) {
console.log(name.substring(0,count)); printMyName(name, ++count); }}console.log(printMyName("Bhargav".1));
/*
B
Bh
Bha
Bhar
Bharg
Bharga
Bhargav
*/
// withotu recursion
var name = "Bhargav"
var output = "";
for(let i=0; i<name.length; i++) {
output = output + name[i];
console.log(output);
}
Copy the code
combination
In React, we split functionality into small, reusable, pure functions, and we had to put all of those reusable functions together to eventually make it into a product. The combination of all the smaller functions into larger functions and, ultimately, an application is called a combination.
There are many different ways to implement composition. One common method we know from Javascript is linking. Linking is a method of using dot notation to call a function that returns the value of the previous function.
Here’s an example. We have a name, if firstName and lastName are greater than 5 words in capital letters, just return, and print the name and length of the name.
const name = "Bhargav Bachina";
const output = name.split("")
.filter(name= > name.length > 5)
.map(val= > {
val = val.toUpperCase();
console.log("Name:::::"+val);
console.log("Count::::"+val.length);
return val;
});
console.log(output)
/*
Name:::::BHARGAV
Count::::7
Name:::::BACHINA
Count::::7
[ 'BHARGAV', 'BACHINA' ]
*/
Copy the code
In React, we use a different approach than linking, because if you have 30 of these functions, it’s hard to link. The goal here is to combine all the simpler functions to produce a higher-order function.
const name = compose(
splitmyName,
countEachName,
comvertUpperCase,
returnName
)
console.log(name);
Copy the code
What is the React
React is a simple javascript UI library for building efficient, fast user interfaces. It is a lightweight library, so it is popular. It follows component design patterns, declarative programming patterns, and functional programming concepts to make front-end applications more efficient. It uses the virtual DOM to manipulate the DOM effectively. It follows a one-way data flow from higher-order components to lower-order components.
How is React different from Angular?
Angular is a full-fledged MVC framework with many specific features such as services, directives, templates, modules, parsers, and so on. React is a very lightweight library that focuses only on the view part of MVC.
Angular follows a two-way flow of data, whereas React follows a one-way flow from top to bottom. React gives developers a lot of freedom when developing features, such as how the API is called, routing, and so on. We do not need to include the router library unless we need it in our project.
What is a Virtual DOM and how does it work
React uses the Virtual DOM to update the real DOM for efficiency and speed. Let’s talk about this in detail.
What is a Virtual DOM
Browsers follow HTML directives to construct the document Object model (DOM). When the browser loads the HTML and renders the user interface, all elements in the HTML document become DOM elements.
DOM is a hierarchy of elements starting from the root element. For example, look at the following HTML.
<div>
<div>
<h1>This is heading</h1>
<p>this is paragraph</p>
<div>
<p>This is just a paragraon</p>
</div>
</div>
<div>
<h1>This is heading</h1>
<p>this is paragraph</p>
<div>
<p>This is just a paragraon</p>
</div>
</div>
<div>
<h1>This is heading</h1>
<p>this is paragraph</p>
<div>
<p>This is just a paragraon</p>
</div>
</div>
</div>
Copy the code
When the HTML is loaded in the browser, all of these HTML elements are converted to DOM elements, as shown below
When the SPA application is involved, the index. HTML is loaded for the first time, and either the updated data or another HTML is loaded in the index. HTML itself. As the user browses the site, we update the same index.html with new content. Every time the DOM changes, the browser needs to recalculate the CSS, lay it out, and redraw the Web page.
React uses the Virtual DOM to effectively recreate the DOM. For us, this makes a very complex and time-consuming task of DOM manipulation much easier. React abstracts all of this from developers to build efficient UIs with the help of the Virtual DOM.
How does the virtual DOM work
The virtual DOM is nothing more than a javascript object representation of the real DOM. Updating javascript objects is easier and faster than updating the real DOM. With that in mind, let’s see how it works.
React saves the entire COPY of the DOM as a virtual DOM
Each time there is an update, it maintains two virtual DOMs to compare the previous state with the current state, and to determine which objects have changed. For example, paragraph text changes to change.
Now, it compares the two virtual DOM differences and updates those changes to the real DOM
Once the real DOM is updated, it also updates the UI
What is the JSX
JSX is a syntax extension to javascript. It’s like a template language with all the functionality of javascript. It generates React elements, which are rendered in the DOM. React recommends using JSX for components. In JSX, we combine javascript and HTML and generate react elements that can be rendered in the DOM.
Here is an example of JSX. We can see how javascript and HTML can be combined. If the HTML contains any dynamic variables, we should use the expression {}.
import React from 'react';
export const Header = (a)= > {
const heading = 'TODO App'
return(
<div style={{backgroundColor:'orange'}} >
<h1>{heading}</h1>
</div>)}Copy the code
The possible bugs after the deployment of code can not be known in real time, in order to solve these bugs, spent a lot of time log debugging, here by the way to recommend you a good BUG monitoring toolFundebug.
Components and different types
Everything in React is a component. We often break down the entire logic of an application into small, individual parts. We call each individual part a component. Typically, a component is a javascript function that takes input, processes it, and returns the React element rendered in the UI.
There are different types of components in React. Let’s take a closer look.
Function/stateless/display component
A function or stateless component is a pure function that accepts arguments and returns a React element. These are pure functions without any side effects. These components have no state or lifecycle methods. Here is an example.
import React from 'react';
import Jumbotron from 'react-bootstrap/Jumbotron';
export const Header = (a)= > {
return(
<Jumbotron style={{backgroundColor:'orange'}} >
<h1>TODO App</h1>
</Jumbotron>)}Copy the code
Class/stateful component
A class or stateful component with a state and lifecycle may change the state of the component through the setState() method. The class component is created using the React extension. It is initialized in the constructor and may have child components. Here is an example.
import React from 'react';
import '.. /App.css';
import { ToDoForm } from './todoform';
import { ToDolist } from './todolist';
export class Dashboard extends React.Component {
constructor(props){
super(props);
this.state = {
}
}
render() {
return (
<div className="dashboard">
<ToDoForm />
<ToDolist />
</div>); }}Copy the code
The controlled components
Controlled components are a technique for processing input forms in React. Form elements typically maintain their own state, whereas React maintains state in a component’s state attribute. We can combine the two to control the input form. This is called a controlled component. Therefore, in the controlled component form, the data is processed by the React component.
Here’s an example. When the user enters a name in the Todo item, a javascript function called handleChange is called to capture the data for each input and put it into a state, thus using the data in handleSubmit.
import React from 'react';
import Form from 'react-bootstrap/Form';
import Button from 'react-bootstrap/Button';
import Row from 'react-bootstrap/Row';
import Col from 'react-bootstrap/Col';
export class ToDoForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: ' '};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('A name was submitted: ' + this.state.value);
event.preventDefault();
}
render() {
return( <div className="todoform"> <Form> <Form.Group as={Row} controlId="formHorizontalEmail"> <Form.Label column sm={2}> <span className="item">Item</span> </Form.Label> <Col sm={5}> <Form.Control type="text" placeholder="Todo Item" /> </Col> <Col sm={5}> <Button variant="primary" type="submit">Add</Button> </Col> </Form.Group> </Form> </div> ); }}Copy the code
Uncontrolled component
In most cases, controlled components are recommended. There is a method called uncontrolled component that works with form data by using the Ref. In uncontrolled components, refs are used to access form values directly from the DOM, rather than event handlers.
We built the same form using Ref instead of React state. We define the Ref using react.createref () and pass the input form and access the form value directly from the DOM in the handleSubmit method.
import React from 'react';
import Form from 'react-bootstrap/Form';
import Button from 'react-bootstrap/Button';
import Row from 'react-bootstrap/Row';
import Col from 'react-bootstrap/Col';
export class ToDoForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: ' '};
this.input = React.createRef();
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit(event) {
alert('A name was submitted: ' + this.input.current.value);
event.preventDefault();
}
render() {
return( <div className="todoform"> <Form> <Form.Group as={Row} controlId="formHorizontalEmail"> <Form.Label column sm={2}> <span className="item">Item</span> </Form.Label> <Col sm={5}> <Form.Control type="text" placeholder="Todo Item" ref={this.input}/> </Col> <Col sm={5}> <Button variant="primary" onClick={this.handleSubmit} type="submit">Add</Button> </Col> </Form.Group> </Form> </div> ); }}Copy the code
Container components
The container component is the component that handles getting data, subscribing to redux storage, and so on. They contain presentation components and other container components, but they never have HTML in them.
High order component
A higher-order component is a component that takes a component as a parameter and generates another component. Redux Connect is an example of a higher-order component. This is a powerful technique for generating reusable components.
Props and State
Props is a read-only property passed to the component to render the UI and state. We can change the component’s output over time.
Here is an example of a class component that defines props and state in its constructor. Whenever this.setState() is used to change the state, the render() function is called again to change the output of the component in the UI.
import React from 'react';
import '.. /App.css';
export class Dashboard extends React.Component {
constructor(props){
super(props);
this.state = {
name: "some name"
}
}
render() {
// reading state
const name = this.state.name;
//reading props
const address = this.props.address;
return (
<div className="dashboard">
{name}
{address}
</div>); }}Copy the code
What is a PropTypes
As applications grow larger over time, type checking is important. PropTypes provides type checking for components and provides good documentation for other developers. If your React project does not use Typescript, it is recommended to add PropTypes to your components.
If a component does not receive any props, we can also define a default props for each component to display. Here’s an example. UserDisplay has three props :name, Address, and age, and we are defining the default props and prop types for them.
import React from 'react';
import PropTypes from 'prop-types';
export const UserDisplay = ({name, address, age}) = > {
UserDisplay.defaultProps = {
name: 'myname'.age: 100.address: "0000 onestreet"
};
return (
<>
<div>
<div class="label">Name:</div>
<div>{name}</div>
</div>
<div>
<div class="label">Address:</div>
<div>{address}</div>
</div>
<div>
<div class="label">Age:</div>
<div>{age}</div>
</div>
</>
)
}
UserDisplay.propTypes = {
name: PropTypes.string.isRequired,
address: PropTypes.objectOf(PropTypes.string),
age: PropTypes.number.isRequired
}
Copy the code
How to update status and how not to
You should not modify the state directly. You can define the state value in the constructor. Direct use of state does not trigger re-rendering. React merges states when it uses this.setState().
// Wrong way
this.state.name = "some name"
// The correct way
this.setState({name:"some name"})
Copy the code
It is always safer to use the second form of this.setstate () because the updated props and state are asynchronous. Here, we update the status with these props.
// Wrong way
this.setState({
timesVisited: this.state.timesVisited + this.props.count
})
// The correct way
this.setState((state, props) = > {
timesVisited: state.timesVisited + props.count
});
Copy the code
Component lifecycle approach
Components go through a series of lifecycle methods as they enter and leave the DOM, which are described below.
componentWillMount()
Called before rendering, on the client side and on the server side, it only happens once.
componentDidMount()
Called after the first render, only on the client side. The component has then generated the corresponding DOM structure, which can be accessed via this.getDomNode (). If you want to use it with other JavaScript frameworks, you can call setTimeout, setInterval, or send AJAX requests in this method (to prevent different actions from blocking the UI).
componentWillReceiveProps()
Called when the component receives a new (updated) prop. This method is not called when render is initialized.
shouldComponentUpdate()
Returns a Boolean value. Called when a component receives a new props or state. Not called during initialization or when forceUpdate is used. This can be used when you are sure that you do not need to update components.
componentWillUpdate()
Called when a component receives a new props or state but has not yet rendered. Will not be called during initialization.
componentDidUpdate()
Called immediately after the component is updated. Will not be called during initialization.
componentWillUnMount()
Is called as soon as the component is removed from the DOM.
getDerivedStateFromError()
This lifecycle method is used in the ErrorBoundary class. In fact, if you use this lifecycle method, any class will become ErrorBoundary. This is used to render the fallback UI when an error occurs in the component tree, rather than showing some weird error on the screen.
componentDidCatch()
This lifecycle method is used in the ErrorBoundary class. In fact, if you use this lifecycle method, any class will become ErrorBoundary. This is used to log errors when they occur in the component tree.
Beyond the combination of inheritance
In React, we always use composition instead of inheritance. We’ve discussed what composition is in the functional programming section. This is a technique that combines simple reusable functions to generate higher-order components. As an example of a combination, we use two widgets todoForm and todoList in the Dashboard component.
import React from 'react';
import '.. /App.css';
import { ToDoForm } from './todoform';
import { ToDolist } from './todolist';
export class Dashboard extends React.Component {
render() {
return (
<div className="dashboard">
<ToDoForm />
<ToDolist />
</div>); }}Copy the code
How do I apply styles in React
There are three ways to apply styles to React components.
External style sheet
In this method, you can import the external stylesheet into the component usage class. But you should use className instead of class to style React elements. Here’s an example.
import React from 'react';
import './App.css';
import { Header } from './header/header';
import { Footer } from './footer/footer';
import { Dashboard } from './dashboard/dashboard';
import { UserDisplay } from './userdisplay';
function App() {
return (
<div className="App">
<Header />
<Dashboard />
<UserDisplay />
<Footer />
</div>
);
}
export default App;
Copy the code
Inline style
In this method, we can pass the props directly to the HTML element with the attribute style. Here’s an example. The important thing to note here is that we are passing the javascript object to style, which is why we use backgroundColor instead of the CSS method backbackground-color.
import React from 'react';
export const Header = (a)= > {
const heading = 'TODO App'
return(
<div style={{backgroundColor:'orange'}} >
<h1>{heading}</h1>
</div>)}Copy the code
Define the style object and use it
Since we pass the javascript object to the style property, we can define a style object in the component and use it. Here’s an example. You can also pass this object as props to the component tree.
import React from 'react';
const footerStyle = {
width: '100%'.backgroundColor: 'green'.padding: '50px'.font: '30px'.color: 'white'.fontWeight: 'bold'
}
export const Footer = (a)= > {
return(
<div style={footerStyle}>
All Rights Reserved 2019
</div>)}Copy the code
What is Redux and how it works
Redux is a state management library for React, based on Flux. Redux simplifies the one-way data flow in React. Redux abstracts state management entirely from React.
How does it work
In React, components connect to redux. To access redux, they send an action containing the ID and payload. The payload in the Action is optional, and the action forwards it to the Reducer.
When the Reducer receives the Action, the Reducer uses the SWITHC… Case syntax compares the type in action. When matched, update the corresponding content to return the new state.
When the Redux state changes, the component connected to Redux will receive the new state as props. When the component receives these props, it enters the update phase and rerenders the UI.
Redux loop details
Let’s look at the entire Redux loop in detail.
Action: Action is just a simple JSON object with type and payload as the key. Type is mandatory; Payload is optional. Here is an example of an action.
// action
{
type:"SEND_EMAIL".payload: data
};
Copy the code
Action Creators: These are the functions that create Actions, so we don’t have to manually write each Action in the component when distributing them. Here is an example of Action Creator.
// action creator
export function sendEamil(data) {
return { type:"SEND_EMAIL".payload: data};
}
Copy the code
Reducers: Reducers are pure functions that take the action and the current state as arguments, compute the necessary logic, and return a new state. These Reducers have no side effects. It doesn’t change state but it always returns state.
export default function emailReducer(state = [], action){
switch(action.type) {
case "SEND_EMAIL": return Object.assign({}, state, {
email: action.payload
});
default: returnstate; }}Copy the code
How does the component interact withredux
To connect
MapStateToProps: This function maps state to the props, so whenever state changes, the new state is remapped to the props. That’s how you subscribe to the Store.
MapDispatchToProps: Apply the Action creators to your props. So we can dispatch an action using this.props.actions.sendemail() in line 12.
Connect and bindActionCreators from Redux. The former is used to connect the store, as in line 22, and the latter is used to bind Action Creators to your props, as in line 20.
// import connect
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
// import action creators
import * as userActions from '.. /.. /.. /actions/userActions';
export class User extends React.Component {
handleSubmit() {
// dispatch an action
this.props.actions.sendEmail(this.state.email); }}// you are mapping you state props
const mapStateToProps = (state, ownProps) = > ({user: state.user})
// you are binding your action creators to your props
const mapDispatchToProps = (dispatch) = > ({actions: bindActionCreators(userActions, dispatch)})
export default connect(mapStateToProps, mapDispatchToProps)(User);
Copy the code
What is React Router Dom and how it works
React-router-dom is a library for routing in applications. There is no routing in the React library and react-router-dom needs to be installed separately.
React-router-dom provides two routers, the BrowserRouter and the HashRoauter. The former is based on the PATHname segment of the URL, while the latter is based on the hash segment.
The former: http://127.0.0.1:3000/article/num1 the latter: http://127.0.0.1:3000/#/article/num1
Copy the code
The react – the router – dom components
BrowserRouter
和HashRouter
It’s a router.Route
Used for route matching.Link
Components are used to create links in the application. It is rendered as an anchor tag in the HTML.NavLink
Is a special link that highlights the currently active link.Switch
Not required, but useful when composing routes.Redirect
Mandatory route redirection
Here are some examples of Link, NavLink, and Redirect in components
// normal link
<Link to="/gotoA">Home</Link>
// link which highlights currentlu active route with the given class name
<NavLink to="/gotoB" activeClassName="active">
React
</NavLink>
// you can redirect to this url
<Redirect to="/gotoC" />
Copy the code
Here is an example of the React Router component. If you look at the following example, we will match the path and render the corresponding component using Switch and Route.
import React from 'react'
// import react router DOM elements
import { Switch, Route, Redirect } from 'react-router-dom'
import ComponentA from '.. /common/compa'
import ComponentB from '.. /common/compb'
import ComponentC from '.. /common/compc'
import ComponentD from '.. /common/compd'
import ComponentE from '.. /common/compe'
const Layout = ({ match }) = > {
return( <div className=""> <Switch> <Route exact path={`${match.path}/gotoA`} component={ComponentA} /> <Route path={`${match.path}/gotoB`} component={ComponentB} /> <Route path={`${match.path}/gotoC`} component={ComponentC} /> <Route path={`${match.path}/gotoD`} component={ComponentD} /> <Route path={`${match.path}/gotoE`} component={ComponentE} /> </Switch> </div> )} export default LayoutCopy the code
What is an error boundary
In React, we usually have a component tree. If any one component fails, it destroys the entire component tree. There is no way to catch these errors, and we can handle them gracefully with error boundaries.
Error boundaries do two things
- If an error occurs, the rollback UI is displayed
- Record the error
Here is an example of the ErrorBoundary class. If a class implements either getDerivedStateFromError or componentDidCatch, then the class becomes an ErrorBoundary. The former returns {hasError: true} to render the fallback UI, while the latter is used to record errors.
import React from 'react'
export class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
// Update state so the next render will show the fallback UI.
return { hasError: true };
}
componentDidCatch(error, info) {
// You can also log the error to an error reporting service
console.log('Error::::', error);
}
render() {
if (this.state.hasError) {
// You can render any custom fallback UI
return <h1>OOPS! . WE ARE LOOKING INTO IT.</h1>;
}
return this.props.children; }}Copy the code
Here’s how we used ErrorBoundary in one of the components. Use the ErrorBoundary class to wrap the ToDoForm and ToDoList. If any errors occur in these components, we log the errors and display the fallback UI.
import React from 'react';
import '.. /App.css';
import { ToDoForm } from './todoform';
import { ToDolist } from './todolist';
import { ErrorBoundary } from '.. /errorboundary';
export class Dashboard extends React.Component {
render() {
return (
<div className="dashboard">
<ErrorBoundary>
<ToDoForm />
<ToDolist />
</ErrorBoundary>
</div>); }}Copy the code
What is the Fragments could
In React, we need to have a parent element and return the React element from the component. Sometimes it can be annoying to add extra nodes to the DOM. Using Fragments, we do not need to add additional nodes to the DOM. We just need to use React.Fragment or <> to wrap the contents. As follows:
// Without Fragments
return (
<div>
<CompoentA />
<CompoentB />
<CompoentC />
</div>
)
// With Fragments
return (
<React.Fragment>
<CompoentA />
<CompoentB />
<CompoentC />
</React.Fragment>
)
// shorthand notation Fragments
return (
<>
<CompoentA />
<CompoentB />
<CompoentC />
</>
)
Copy the code
What is a Portal?
By default, all child components are rendered on the UI, depending on the component hierarchy. Portal provides an excellent solution for rendering child nodes to DOM nodes that exist outside the parent component.
Here’s an example. By default, a parent component has children in the DOM hierarchy.
We can remove the children component from the parent component and append it to the Dom node with id someID.
First, getting the ID someID, we create an element div in Constructor to append the Child to the someRoot in componentDidMount. Finally, we pass the child node to the specific DOM node with the help of reactdom.createPortal (this.props. Childen), domNode.
First, get the DOM element with id someid, then create an element div in the constructor, and put someRoot in the div in the componentDidMount method. Finally, pass the children to the corresponding node via reactdom.createPortal (this.props. Childen), domNode.
const someRoot = document.getElementById('someid');
class Modal extends React.Component {
constructor(props) {
super(props);
this.el = document.createElement('div');
}
componentDidMount() {
someRoot.appendChild(this.el);
}
componentWillUnmount() {
someRoot.removeChild(this.el);
}
render() {
return ReactDOM.createPortal(
this.props.children,
this.el, ); }}Copy the code
What is context
Sometimes we must pass props to the component tree, even if none of the intermediate components need them. Context is a way to pass props without passing the component tree at each level.
What is the Hooks
Hooks are new in React version 16.8. Remember, we cannot use state in function components because they are not class components. Hooks allow us to use state and other functionality in function components.
There are no major changes, so we don’t have to drop the class component.
Hook will not affect your understanding of React concept. Instead, hooks provide a more direct API for known React concepts: props, state, context, refs, and lifecycle. As we will see later, hooks also provide a more powerful way to combine them.
We can use hooks such as useState, useEffect, useContext, useReducer, etc.
Here are the basic rules of Hooks
- Hooks should be used on the outside. They should not be used inside loops, conditions, or nested functions
- Hooks should only be used in function components.
Let’s look at an example to understand hooks. This is a function component that takes props and displays them on the UI. With the help of the useState hook, we convert this function component into a stateful component. First, we define the state in line 5, which is equivalent to
constructor(props) {
super(props);
this.state = {
name:'myname'.age:10.address:'0000 one street'}}Copy the code
UseState returns two items, one for user and the other for the setUser function. User is an object that can be used directly without the this keyword. SetUser is a function that can be used to set the state when the user clicks the button on line 21, which is equivalent to the following:
this.setState({name:'name changed'})
Copy the code
import React, { useState } from "react";
export const UserDisplay = ({ name, address, age }) = > {
const [user, setUser] = useState({
name: "myname".age: 10.address: "0000 onestreet"
});
return (
<>
<div>
<div class="label">Name:</div>
<div>{user.name}</div>
</div>
<div>
<div class="label">Address:</div>
<div>{user.address}</div>
</div>
<div>
<div class="label">Age:</div>
<div>{user.age}</div>
</div>
<button onClick={()= > setUser({ name: "name changed" })}>
Click me
</button>
</>
);
};
Copy the code
How to improve performance
There are many ways to improve application performance, but these are important:
- Use appropriately
shouldComponentUpdate
Life cycle approach. It avoids unnecessary rendering of child components. If there are 100 components in the tree, do not re-render the entire component tree to improve application performance. - use
create-react-app
To build the project, which creates the entire project structure and does a lot of optimization. - Immutability is the key to improving performance. Do not modify the data, but always create new collections on top of existing ones to keep replication to a minimum and improve performance.
- Always used when displaying a list or table
Keys
, which will make React update faster - Code separation is the technique of inserting code into separate files, loading only the required files for a module or part.
How do I preserve the data when the page is reloaded
The single-page application first loads the index.html in the DOM, then loads the content as the user browses the page, or retrieves any data from the back-end API in the same index.html.
If we reload the page index.html by clicking the Reload button in the browser, the entire React app will reload and we’ll lose the app’s state. How do I retain the application state?
Each time the application is reloaded, we use browser localstorage to save the state of the application. We keep the entire storage data in localstorage, and every time there is a page refresh or reload, we load the state from localstorage.
How do I make API calls in React
We use Redux-Thunk to call the API in React. Because Reduce is a pure function, there are no side effects, such as calling apis.
Therefore, we must use Redux-Thunk to make the API call from Action Creators. The Action Creator dispatches an Action, putting the data from the API into the payload of the Action. Reducers receives the data we discussed in the redux loop above, and the rest of the process is the same.
Redux-thunk is a middleware. Once it is introduced into a project, every time an action is dispatched, it is passed through Thunk. If it is a function, it simply waits for the function to process and returns a response. If it’s not a function, it’s just handled normally.
Here’s an example. SendEmailAPI is a function called from a component that takes a data and returns a function with Dispatch as an argument. We call the API apiservice with redux-Thunk and wait for a response. Once the response is received, we send an action using payload.
import apiservice from '.. /services/apiservice';
export function sendEmail(data) {
return { type:"SEND_EMAIL".payload: data };
}
export function sendEmailAPI(email) {
return function(dispatch) {
return apiservice.callAPI(email).then(data= >{ dispatch(sendEmail(data)); }); }}Copy the code
conclusion
To have a good interview, you must have a thorough understanding of all of the above topics. Even if you’re currently using React, understanding these concepts can give you confidence in the workplace.