The React β οΈ
React is a JavaScript library for developing user interfaces that was created by Facebook in 2013. React integrates many exciting components, libraries, and frameworks. Of course, developers can also develop components themselves.
Prior to best practices, I recommend using test-driven development (TDD) when developing React applications. Test-driven development means first writing a test and then developing your code based on that test, which makes it easier to identify errors.
This article translated from Medium:towardsdatascience.com/react-best-… Has been authorized by the author β€, translation is not easy, like – favorites – comments is the biggest encouragement to me! οΈ
Best practices
directory
- File organization
- Small functional components
- Reusable components
- Remove redundant code
- Index as key
- Needless to add
<div>
- Provide only necessary comments
- Understand how to handle ‘this’
- Props-State-Constructor
- Think about naming components after you write them
- Pay attention to State and Rendering
- Avoid using objects in setState
- Use capital camel name
- Use prop – types
- Write CSS in JavaScript
- test
- Use ESLint, Prettier, and Snippet libraries
- Use the React Developer tool
1. File organization π
File organization is a best practice not only for React applications, but for other applications as well. The Create React App file structure is one possible way to organize React files. While you can’t say that one way of organizing documents is better than another, it’s important to keep your documents organized.
In React, the number of code files ballooned as applications grew, because each component had at least one file associated with it.
Assets folder
Create an Assets folder that contains the top-level CSS files, images, and Fonts files.
Helpers folder
Maintain a helpers folder where files for other functionality are stored.
The Components folder
Keep all component-related files in one folder. Typically, the Components folder contains multiple component files, such as test files, CSS, and one or more component files. If only specific components use any secondary components, it is a good idea to save these widgets in the Components folder. It is easier to understand the file hierarchy when you keep large components in their own folders and smaller components used by components in subfolders.
Organize files using package.json
The developers mainly name the main component file as the **index.js ** file. Once you have several files, all named index.js, navigation becomes cumbersome. The solution to this problem is to add package.json files to each component folder and set the main entry point for the corresponding folder.
For example, for Button components, the main entry point is button.js. It’s not a good idea to add package.json to each folder, but it makes it easier to work with files. Therefore, we can add the following package.json file to the SRC/Components /button folder.
{
"main": "Button.js"
}
Copy the code
Organize by style
When you use Redux in a Redux project, you can use a Rails style, Domain style, or “Ducks” mode folder structure depending on the project.
Create separate “Action”, “Constants”, “Reducers”, “Containers”, and “Components” folders in a Rails style pattern.
/actions/user.js
/components/user.js
/reducers/user.js
/containers/index.js
Copy the code
In the Domain style pattern, separate folders are used for each feature or Domain, and perhaps subfolders are used for each file type.
/users/components/index.js
/users/actions/index.js
/users/reducers/index.js
Copy the code
The “Duck” pattern is similar to the domain style, but it usually explicitly links actions and reducers together by defining them in the same file. Here is an organized module called Widgets:
// widgets.js
// Actions
const LOAD = 'my-app/widgets/LOAD';
const CREATE = 'my-app/widgets/CREATE';
const UPDATE = 'my-app/widgets/UPDATE';
const REMOVE = 'my-app/widgets/REMOVE';
// Reducer
export default function reducer(state = {}, action = {}) {
switch (action.type) {
// do reducer stuff
default: returnstate; }}// Action Creators
export function loadWidgets() {
return { type: LOAD };
}
export function createWidget(widget) {
return { type: CREATE, widget };
}
export function updateWidget(widget) {
return { type: UPDATE, widget };
}
export function removeWidget(widget) {
return { type: REMOVE, widget };
}
Copy the code
The new team suggested developing React apps in Duck style. As the team matures, it will start using the Rails style. Rails has the advantage of being able to easily understand projects.
Dan Abramov tweeted a solution
Move the file around until it feels right.
That’s exactly what you should do. You should move the files around until they feel right.
2. Small functional components π€
React is also known to work well with large components. But if we break them down into smaller sizes, we can reuse them. Small components are easier to read, test, maintain, and reuse. Most beginners in React create class components without even using component state or lifecycle methods. Function components are more efficient to write than class components.
import React, { Component } from 'react';
class Button extends Component {
Β render() {
Β Β const { children, color, onClick } = this.props;
Β Β return (
Β Β Β <button onClick={onClick} className={`BtnThe ${color} `} >
Β Β Β Β {children}
Β Β Β </button>); }}export default Button;
Copy the code
The Class component above can be written as follows.
import React from 'react';
export default function Button({ children, color, onClick }) {
return (
<button onClick={onClick} className={`BtnThe ${color} `} >
{children}
</button>
);
}
Copy the code
Advantages of using functional components.
- Less code
- Easier to understand
- stateless
- Easier to test
- There is no
this
Binding. - It is easier to extract smaller components.
When you use functional components, you have no control over the re-render process in functional components. React will re-render the functional component when something changes. If you use Component components, you can control the rendering of components. In previous React versions, there was a solution that used React.Purecomponent. Purecomponent allows shallow comparisons of props and state. When the props or state changes, the component is rerendered. Otherwise, the PureComponent will skip re-render and revert to the rendered result last time.
After React V16.6.0, React introduced a new feature called Memo. Memo makes a shallow comparison of props. When the props or state changes, the component is rerendered. React based on comparison either reuses or rerenders the result of the last render. Memo allows you to create a purely functional component so that even functional components can control the rendering of the component, so we don’t need to use stateful components and pureComponents.
Component, image source:www.kirupa.com/react/image…
3. Reusable components β»οΈ
Each functional component should have a function, which means that a functional component is equal to a function. When you create a functional component using a function, you increase the reusability of that component.
4. Delete redundant codes ποΈ
Not only in React, but in all application development, the general rule is to keep code as clean and small as possible. React best practices dictate that you keep your code error-free and concise. Don’t Repeat Yourself (DRY) is a principle of software development that strives to minimize the duplication of software patterns, replace it with abstraction, or use data normalization to avoid redundancy. You can use your own Style Guide when writing code, or use a popular and mature Style Guide (Airbnb React/JSX Style Guide, Facebook Style Guide, etc.). If you start using one of these code styles, don’t get confused with the others.
Photo source:Quotefancy.com/quote/46568…
5. The index serves as the key π
When creating an array of JSX elements, React needs to add a key attribute to the element. This is usually done by using the map function, which causes people to use Index to set the Key property. This is too bad! React uses the key property to trace every element in an array, due to the collapsible nature of arrays. However, if you use Index as the Key attribute, it will usually lead to errors when iterating to generate a stateful array of class components, so you should avoid using Index as the Key attribute.
6. Unnecessarydiv
π«
When creating the React component, it’s important to remember that you’re still building HTML documents. People tend to get delimiters in React, which ends up with incorrect HTML.
return (
<div>
<li>Content</li>
</div>
);
Copy the code
In the above example, div ends up being a direct child of UL, which is incorrect HTML, while in the following example li ends up being a direct child of UL, which makes correct HTML.
return (
<li>Content</li>
);
Copy the code
The alternative is to use the react. Fragment method. React. fragments were introduced in Reaction V16.2, and we can use them without using div’s that cause misformatting.
7. Add only necessary comments π
Add comments to the application only when necessary. Without exception, removing comments from an application meant I had to write extra code line by line based on comments. Comments in general are a weakness that dictates bad design, especially verbose comments, and it’s clear that developers don’t know what they’re doing and try to remedy it by writing comments.
Photo source:www.toptal.com/sql/guide-t…
8. Know how to handle itthis
π
Because function components do not require this bindings, use them whenever possible. But if you’re using an ES6 class, you’ll need to bind the class manually because React can’t automatically bind functions in this component. Here are some examples of this.
Example 1: Bind at render time
class Foo extends Components {
constructor(props) {
super(props);
this.state = { message: "Hello" };
}
logMessage() {
const { message } = this.state;
console.log(message);
}
render() {
return (
<input type="button" value="Log" onClick={this.logMessage.bind(this)} />); }}Copy the code
The function above has the following this binding:
onClick={this.logMessage.bind(this)}
Copy the code
This method is clear, concise, and efficient, but it can lead to a slight performance problem because a new logMessage function will be called frequently every time the component re-rasterizes. Example 2: Arrow function in render function.
class Bar extends Components {
constructor(props) {
super(props);
this.state = { message: "Hello" };
}
logMessage() {
const { message } = this.state;
console.log(message);
}
render() {
return (
<input type="button" value="Log" onClick={()= >this.logMessage()} /> ); }}Copy the code
The this binding above looks like this:
onClick={() => this.logMessage()}
Copy the code
This approach is very neat, as in Example 1, but as in example 1, it also creates a new logMessage function each time the component is rendered. Example 3: Bind *** this in the constructor
class Hello extends Components {
constructor(props) {
super(props);
this.state = { message: "Hello" };
this.logMessage = this.logMessage.bind(this);
}
logMessage() {
const { message } = this.state;
console.log(message);
}
render() {
return (
<input type="button" value="Log" onClick={this.logMessage} />); }}Copy the code
The logic for binding this is as follows:
this.logMessage = this.logMessage.bind(this);
Copy the code
This approach addresses the potential performance issues of examples 1 and 2. But don’t forget to call super in the constructor. Example 4: Arrow function in the Class property
class Message extends Components {
constructor(props) {
super(props);
this.state = { message: "Hello" };
}
logMessage = (a)= > {
const { message } = this.state;
console.log(message);
}
render() {
return (
<input type="button" value="Log" onClick={this.logMessage} />); }}Copy the code
Bind this fragment as follows:
logMessage = (a)= > {
const { message } = this.state;
console.log(message);
}
Copy the code
This approach is clean, readable, avoids the performance problems of examples 1 and 2, and avoids duplication in Example 3. Note, however, that this approach does rely on experimental features, and it is not an official part of the ECMAScript specification. You can experiment with this language functionality by installing and configuring the Babel package, and the application created by the Create React app configures many useful features, including the above.
Photo source:Codeburst. IO/javascript -…
9. Props — State — Constructor π
We can divide the title into two subheadings, such as:
- Do not use Props in the initial state.
- Do not initialize component state in a class constructor.
When you use props in the initial state, the problem is that the constructor is called when the component is created. So the constructor is called only once. If the next time the props changes, the component state is not updated and remains the same as the previous value. You can fix the problem using the response life cycle method componentDidUpdate. The componentDidUpdate method updates the component when the props changes. Although componentDidUpdate is not called in the initial rendering. However, it is not a best practice to use props in its initial state.
Initializing the state as a class field is a best practice. Using constructors to initialize component state is not bad practice, but it adds redundancy in the code and causes some performance problems. When you initialize state in a class constructor, it needs to call super and remember props, which can cause performance problems.
class SateInsideConstructor extends React.Component {
constructor(props) {
super(props)
this.state = {
counter: 0}}/* your logic */
}
Copy the code
Another question is, when you initialize state in a constructor, consider the number of lines you need. Do you need constructor (), super ()?
import React from 'react'
class MyComponent extends React.Component {
state = {
counter: 0
}
/* your logic */
}
Copy the code
Indepth. Dev/the depth – in the ex…
10. Name π after
Name a function or component after you write the component code, because you know what it does. For example, you can immediately select the name of a component like a FacebookButton based on the component code. But in the future, you could use this component as a TwitterButton, YoutubeButton. Therefore, the best practice is to name the component Button. In general, when you finish a function, you should be able to select common names for components and functions. Post-naming increases reusability.
11. Pay attention to State and Rendering π
In React, when we can sort components by state. Stateful and stateless. Stateful components store component state information and provide the necessary context. For stateless components, you cannot provide context to parts of the user interface because you cannot maintain state. Stateless components are scalable and reusable, just like pure JavaScript functions. To separate the data fetching logic of a stateful component from the render logic of a stateless component, a better approach is to use a stateful component to fetch the data and a stateless component to display the fetched data.
After React V16.08, there is a new feature called React Hooks. React Hooks write stateful function components. React Hooks disable the use of class components.
If the data is not used directly in the rendering, it should not be placed in the component’s State. Data not directly used for rendering may cause unnecessary re-renders.
www.barrymichaeldoyle.com/sub-renderi…
12. Avoid using the object π in setState
React does not guarantee immediate application of setState changes, according to React Docs. Therefore, reading this.state after calling setState can be a potential trap, because this.state may not be what you think it is.
const { ischecked } = this.state;
this.setState({ischecked: !ischecked});
Copy the code
Instead of updating the state in the object as in the code snippet above, we can use the following functions.
this .setState((prevState, props) = > {
return {ischecked: !prevState.ischecked}
})
Copy the code
The function above takes the former state as its first argument and uses props when updating the application as its second argument. Status updates are an asynchronous operation, so to update the state object, we need to use the updater function on setState.
13. Use capital camel name πͺ
When you work with React, remember that you are using JSX (JavaScript extensions) and not HTML. The component you create should be named camel in uppercase, Pascal Case. Camel case means that words have no Spaces and the first letter of each word is capitalized. For example, if you have a component named selectButton, you should name it selectButton, not selectButton. Using capital camel case helps JSX distinguish between default JSX element tags and created elements. However, it is possible to name components using lowercase letters, but this is not a best practice.
Photography is by Artem Sapegin on Unsplash
14. The use ofprop-types
π§ͺ
“Prop-types” is a library for checking props types, which helps prevent errors by making sure you are using the correct data types for props. Since React V15.5, React.PropTypes has been split into a separate package. React.PropTypes enables us to enter props for checking the component and provide a default value for it. Therefore, you will use an external library through the NPM installation.
npm i prop-types
Copy the code
Import the library, add the PropTypes to the component, set the data types accordingly, and if props is necessary, add isRequired as shown below.
import React, { Component } from "react";
import PropTypes from "prop-types";
class Welcome extends Component {
render() {
const { name } = this.props;
return <h1>Welcome, {name}</h1>;
}
}
Welcome.PropTypes = {
name: PropTypes.string.isRequired
};
Copy the code
You can assign a default value for props using defaultProps. When a component does not receive props from the parent component, it uses defaultProps. If you have marked your props as necessary, then there is no need to assign defaultProps. In the code snippet below, you can see all the default values for props assigned to ModalButton. In this case, I use the React Bootstrap framework.
import React, { Component } from "react";
import { Button } from "react-bootstrap";
import PropTypes from 'prop-types'
class ModalButton extends Component {
render() {
return <Button variant={this.props.variant}>{this.props.children}</Button>;
}
}
ModalButton.defaultProps = {
variant: "outline-info".children: "Info"
};
ModalButton.propTypes = {
variant: PropTypes.string,
children: PropTypes.string
}
ReactDOM.render(<ModalButton />, document.getElementById('root'));
Copy the code
Note that PropsTypes is used for type checking after assigning defaultProps. Therefore, it also checks the default values assigned to props.
15. The CSS in JavaScript π
When you have a large CSS (SCSS) file, you can use a global prefix followed by a block-element-modifier convention to avoid name conflicts. As the application grows, this approach is not scalable. So you must evaluate your CSS (SCSS) files. There is another way to Extract CSS via Webpack’s Mini CSS Extract Text plugin (which requires Webpack 4 to work), but it creates a heavy dependency on Webpack. If you use this approach, it is difficult to test components. The best practice is to have an application that is easy to test, so following this approach is not the best practice.
EmotionJS, Glamorous and Styled Components are some of the latest CSS concepts in the JS library. You can use them as required. When you need to compile a CSS for production, you can use the EmotionJS library. When you have a complex topic problem, you can use Glamorous and Styled Components.
WordPress.org/plugins/cus…
16. Testing π
Not just in React, but in other programming languages as well. Testing is important because it ensures that the code works as expected and is easy to test quickly. As a best practice, create a __test__ folder in the Components folder. Prefix the test file.test.js with the name of the component. You can use Jest as the test run program and Enzyme as the test tool for React.
Crashed component testing is a simple and quick way to ensure that all components work properly without crashing. Component crash tests are easy to apply to every component you create.
import React from 'react'
import ReactDom from 'react-dom'
import App from '. '
it('renders without crashing', () = > {const div = document.createElement{'div'};
ReactDOM.render(<App/ >, div);
ReactDOM.unmountComponentAtNode(div);
});
Copy the code
You should obviously test more extensively than crash tests. If you write more test cases, it will provide more test coverage for your code. However, you should at least do some crash component testing. In the crash component test above, what we do is create an element that uses the ReactDom and mounts any components imported into the div we just created, and then unmounts the div.
Real React developers should test the entire React application properly.
17. Use ESLint, Prettier, and Snippet libraries π
ESLint uses various tips to keep your code nice and clean. You can link it to your IDE. The best practice is to create your own ESLint configuration file.
A good developer should fix all ESlint errors and warnings, not disable the error.
Prettier is a code formatting tool. Prettier has a set of rules for formatting and indenting code. You can use Sonarlint to check spelling, function length, and better method suggestions. Using Husky is not only a good practice for React, but also a good practice for Git. You can define husky in package.json files. Husky protects your application from false commits and false pushes.
Snippets help you write the best code and trend syntax. They make your code relatively error-free. You can use many snippet libraries, such as ES7 React, JavaScript (ES6) snippets, and so on.
Photo source:Medium.com/dubizzletec…
18. Use React Developer Toolsπ οΈ
The React developer tool is an extension for Chrome and Firefox. If you use Safari or another browser, install it using the following command.
npm install -g react-devtools@^4
Copy the code
If you use developer tools and are looking for a Web application that uses React, you can see the component hierarchy in the Components TAB. If you click on a component, you can view the Props and State of that component. As you can see, the React Developer Tools extension is a valuable tool for testing and debugging, and for really understanding what’s going on in this application.
Conclusion β οΈ
This article describes best practices in React. These practices improve application performance, application code, and coding skills. π
Happy coding! π
Translation is not easy, so it is the biggest encouragement to me!
Want to learn more exciting practical skills tutorial? Come and visit the Tooquine community.