Hello Readers, CoolMonkTechie heartily welcomes you in this article (Is Composition Better Than Inheritance In React?).
In this article, we will learn about React topic ” Why Composition is better than Inheritance “. We will try to understand which works better in react, Inheritance or Composition using below points:
What are Composition and Inheritance ?
Composition vs Inheritance
Composition – Using props.children
Composition – Child Groups
Composition – Classes Work Too
What about Inheritance ?
Inheritance and Composition are two important parts of object-oriented programming when it comes to code reusability. Both of these concepts are also relevant to React components. Hence, the concept of inheritance vs composition is very important.
A famous quote about learning is :
” He who learns but does not think, is lost! He who thinks but does not learn is in great danger.“
So Let’s begin.
What are Composition and Inheritance ?
Composition and inheritance are the approaches to use multiple components together in ReactJS. This helps in code reuse. React recommends using composition instead of inheritance as much as possible and inheritance should be used in very specific cases only.
Inheritance uses the is-a relationship method. Derived components had to inherit the properties of the base component and it was quite complicated while modifying the behavior of any component. The composition aims for something better. Instead of inheriting the properties of other components, why not inherit only behavior, and add behavior to the desired component?
Composition does not inherit properties, only the behavior. This is a plus point but why? In inheritance, it was difficult to add new behavior because the derived component was inheriting all the properties of parent class and it was quite difficult to add new behavior. We had to add more uses cases. But in composition, we only inherit behavior and adding new behavior is fairly simple and easy.
For example, Let’s say we have a component to input username. We will have two more components to create and update the username field. We extended the UserNameForm component and extracted its method in child component using super.render().
Use of composition is simpler than inheritance and easy to maintain the complexity.
Composition vs Inheritance
React has a powerful composition model, and we recommend using composition instead of inheritance to reuse code between components. We can differentiate the below points between Inheritance and Composition :
Inheritance can be overused.
Composition of behavior can be simpler and easier.
React supports using composition over deep inheritance.
Inheritance inherits the properties of other components while Composition does not inherit properties, only the behavior.
In inheritance, it was difficult to add new behavior because the derived component was inheriting all the properties of parent class and it was quite difficult to add new behavior. We had to add more uses cases. But in composition, we only inherit behavior and adding new behavior is fairly simple and easy.
Composition – Using props.children
Some components don’t know their children ahead of time. This is especially common for components like Sidebar or Dialog that represent generic “boxes”.
We recommend that such components use the special children prop to pass children elements directly into their output. This lets other components pass arbitrary children to them by nesting the JSX.
Anything inside the <FancyBorder> JSX tag gets passed into the FancyBorder component as a children prop. Since FancyBorder renders {props.children} inside a <div>, the passed elements appear in the final output.
/* FancyBorder will componse with children*/
function FancyBorder(props) {
return (
<div className={'FancyBorder FancyBorder-' + props.color}>
{props.children}
</div>
);
}
/* WelcomeDialog uses FancyBorder with children*/
function WelcomeDialog() {
return (
<FancyBorder color="blue">
<h1 className="Dialog-title">
Welcome
</h1>
<p className="Dialog-message">
Thank you for visiting our spacecraft!
</p>
</FancyBorder>
);
}
We can conclude that
Any Components within <FancyBorder> become props.children
The parent component can wrap children in a <div> for layout/style
Composition – Child Groups
While this is less common, sometimes you might need multiple “holes” in a component. In such cases you may come up with your own convention instead of using children.
React elements like <Contacts /> and <Chat /> are just objects, so you can pass them as props like any other data. This approach may remind you of “slots” in other libraries but there are no limitations on what you can pass as props in React.
Sometimes components have children in several places
Assigning the child components to prop names can help organize
Composition – Classes Work Too
Sometimes we think about components as being “special cases” of other components. For example, we might say that a WelcomeDialog is a special case of Dialog.
In React, this is also achieved by composition, where a more “specific” component renders a more “generic” one and configures it with props.
Composition works equally well for components defined as classes.
Specific Components can configure General Components
Props can be used to configure
What about Inheritance ?
Facebook doesn’t use inheritance beyond initial Component Classes
Frontends can be built using a mixture of ‘general’ and ‘specific’ components
Use Props to pass specific attributes and children to render specific behavior
Behavior shared within Components such as logic or utilities can be shared as JavaScript libraries or modules
Using import is more useful and less restricting then extends
That’s all about in this article.
Conclusion
In this article, We understood which works better in react, Inheritance or Composition. Inheritance and composition both can be used for code reusability and for enhancing components but according to the core React team, we should prefer composition over inheritance.
Thanks for reading ! I hope you enjoyed and learned about Composition concept is better than Inheritance in React. Reading is one thing, but the only way to master it is to do it yourself.
Please follow and subscribe us on this blog and and support us in any way possible. Also like and share the article with others for spread valuable knowledge.
You can find Other articles of CoolmonkTechie as below link :
Hello Readers, CoolMonkTechie heartily welcomes you in this article (How To Use Axios with ReactJS ?).
In this article, we will understand how to use Axios with ReactJS. Many projects on the web need to interface with a REST API at some stage in their development. Axios is a lightweight HTTP client based on the $http service within Angular.js v1.x and is similar to the native JavaScript Fetch API. In this article, we will see examples of how to use Axios to access the popular JSON Placeholder API within a React application.
A famous quote about learning is :
” Change is the end result of all true learning.”
So Let’s begin.
Introduction
Axios is promise-based, which gives you the ability to take advantage of JavaScript’s async and await for more readable asynchronous code.
We can also intercept and cancel requests, and there’s built-in client-side protection against cross-site request forgery.
Prerequisites
To follow along with this article, we’ll need the following:
Node.js version 10.16.0 installed on our computer.
A new React project set up with Create React App.
It will also help to have a basic understanding of JavaScript along with a basic knowledge of HTML and CSS.
Steps to Use Axios library
Step 1 – Adding Axios to the Project
In this section, we will add Axios to the axios-tutorial React project. To add Axios to the project, open our terminal and change directories into our project:
$ cd axios-tutorial
Then run this command to install Axios:
$ npm install axios
Next, we will need to import Axios into the file we want to use it in.
Step 2 – Making a GET Request
In this example, we create a new component and import Axios into it to send a GET request.
Inside the src folder of our React project, create a new component named PersonList.js:
First, we import React and Axios so that both can be used in the component. Then we hook into the componentDidMount lifecycle hook and perform a GET request.
We use axios.get(url) with a URL from an API endpoint to get a promise which returns a response object. Inside the response object, there is data that is then assigned the value of person.
We can also get other information about the request, such as the status code under res.status or more information inside of res.request.
Step 3 – Making a POST Request
In this step, we will use Axios with another HTTP request method called POST.
Remove the previous code in PersonList and add the following to create a form that allows for user input and subsequently POSTs the content to an API:
Inside the handleSubmit function, we prevent the default action of the form. Then update the state to the user input.
Using POST gives us the same response object with information that we can use inside of a then call.
To complete the POST request, we first capture the user input. Then we add the input along with the POST request, which will give us a response. We can then console.log the response, which should show the user input in the form.
Step 4 – Making a DELETE Request
In this example, we will see how to delete items from an API using axios.delete and passing a URL as a parameter.
Change the code for the form from the POST example to delete a user instead of adding a new one:
Again, the res object provides us with information about the request. We can then console.log that information again after the form is submitted.
Step 5 – Using a Base Instance in Axios
In this example, we will see how we can set up a base instance in which we can define a URL and any other configuration elements.
Create a separate file named api.js. Export a new axios instance with these defaults:
src/api.js
import axios from 'axios';
export default axios.create({
baseURL: `http://jsonplaceholder.typicode.com/`
});
Once the default instance is set up, it can then be used inside of the PersonList component. We import the new instance like this:
src/PersonList.js
import React from 'react';
import axios from 'axios';
import API from '../api';
export default class PersonList extends React.Component {
handleSubmit = event => {
event.preventDefault();
API.delete(`users/${this.state.id}`)
.then(res => {
console.log(res);
console.log(res.data);
})
}
}
Because http://jsonplaceholder.typicode.com/ is now the base URL, we no longer need to type out the whole URL each time we want to hit a different endpoint on the API.
Step 6 – Using async and await
In this example, we will see how we can use async and await to work with promises.
The await keyword resolves the promise and returns the value. The value can then be assigned to a variable.
In this code sample, the .then() is replaced. The promise is resolved, and the value is stored inside the response variable.
That’s all about in this article.
Conclusion
In this article, We understood how to use Axios with ReactJS. We explored several examples on how to use Axios inside a React application to create HTTP requests and handle responses.
Thanks for reading ! I hope you enjoyed and learned about the Axios library usage in ReactJS. Reading is one thing, but the only way to master it is to do it yourself.
Please follow and subscribe to the blog and support us in any way possible. Also like and share the article with others for spread valuable knowledge.
You can find Other articles of CoolmonkTechie as below link :
Hello Readers, CoolMonkTechie heartily welcomes you in this article.
In this article, we will understand about the rules of React Hooks and how to effectively start using them in our projects. We will discuss the two most important rules of React Hooks and how to effectively think in Hooks.
” React Hooks are a new addition in React 16.8 that let you use state and other React features without writing a class component. In other words, Hooks are functions that let you “hook into” React state and lifecycle features from function components. (They do not work inside class components.)”
A famous quote about learning is :
” The more I live, the more I learn. The more I learn, the more I realize, the less I know. “
So Let’s begin.
What is React Hook?
Hooks are a new addition in React 16.8. They let you use state and other React features without writing a class. It mainly uses to handle the state and side effects in react functional component. React Hooks are a way to use stateful functions inside a functional component. Hooks don’t work inside classes — they let you use React without classesReact provides a few built-in Hooks like useState and useEffect. The React hooks do :
Best practices
Easy to under understand
Easy to test
Increases the performance and so on.
Why React Hook?
There are two reasons to use React hooks :
The first main reason is the Introduce state in a functional component. We know that the states cannot be used in functions. But with hooks, we can use states.
Another reason is the handle side effect in react component. It means, now we can use newly introduced state such as useEffect.
But do we should know for some scenarios, there are 3 places where react fails. While Reuse logic between components :
Has Huge components
Confusing
Rules Of React Hooks
Hooks are JavaScript functions, but we need to follow two rules when using them :
Call Hooks at the top level;
Only call Hooks from React components.
Let’s look at these rules in more detail :
1. Call Hooks At The Top Level
Don’t call Hooks inside loops, conditions, or nested functions. Always use Hooks at the top level of your React function. By following this rule, we ensure that Hooks are called in the same order each time a component renders. That’s what allows React to correctly preserve the state of Hooks between multiple useState and useEffect calls.
Let’s make a Form component which will have two states:
accountName
accountDetail
These states will have default values, we’ll make use of the useEffect hook to persist the state to either the local storage of our browser or to the title of our document.
Now, this component will be maybe to successfully manage its state if it remains the same between multiple calls of useState and useEffect.
function Form() {
// 1. Use the accountName state variable
const [accountName, setAccountName] = useState('Arun');
// 2. Use an effect for persisting the form
useEffect(function persistForm() {
localStorage.setItem('formData', accountName);
});
// 3. Use the accountDetail state variable
const [accountDetail, setAccountDetail] = useState('Active');
// 4. Use an effect for updating the title
useEffect(function updateStatus() {
document.title = accountName + ' ' + accountDetail;
});
// ...
}
If the order of our Hooks changes (which can be possible when they are called in loops or conditionals), React will have a hard time figuring out how to preserve the state of our component.
// ------------
useState('Arun') // 1. Initialize the accountName state variable with 'Arun'
useEffect(persistForm) // 2. Add an effect for persisting the form
useState('Active') // 3. Initialize the accountdetail state variable with 'Active'
useEffect(updateStatus) // 4. Add an effect for updating the status
// -------------
// Second render
// -------------
useState('Arun') // 1. Read the accountName state variable (argument is ignored)
useEffect(persistForm) // 2. Replace the effect for persisting the form
useState('Active') // 3. Read the accountDetail state variable (argument is ignored)
useEffect(updateStatus) // 4. Replace the effect for updating the status
// ...
That’s the order React follows to call our hooks. Since the order remains the same, it will be able to preserve the state of our component. But what happens if we put a Hook call inside a condition?
// We're breaking the first rule by using a Hook in a condition
if (accountName !== '') {
useEffect(function persistForm() {
localStorage.setItem('formData', accountName);
});
}
The accountName !== '' condition is true on the first render, so we run this Hook. However, on the next render the user might clear the form, making the condition false. Now that we skip this Hook during rendering, the order of the Hook calls becomes different:
useState('Arun') // 1. Read the accountName state variable (argument is ignored)
// useEffect(persistForm) // This Hook was skipped!
useState('Active') // 2 (but was 3). Fail to read the accountDetails state variable
useEffect(updateStatus) // 3 (but was 4). Fail to replace the effect
React wouldn’t know what to return for the second useState Hook call. React expected that the second Hook call in this component corresponds to the persistForm effect, just like during the previous render — but it doesn’t anymore. From that point on, every next Hook call after the one we skipped would also shift by one — leading to bugs.
This is why Hooks must be called on the top level of our components. If we want to run an effect conditionally, we can put that condition inside our Hook.
2. Only Call Hooks From React Components
Don’t call Hooks from regular JavaScript functions. Instead, you can call Hooks from React function components. Let’s take look at the difference between JavaScript function and React component below:
Here we import the useState hook from the React package, and then declared our function. But this is invalid as it is not a React component.
React Function
import React, { useState} from "react";
import ReactDOM from "react-dom";
function Account(props) {
const [name, setName] = useState("Arun");
return <p>Hello, {name}! The price is <b>{props.total}</b> and the total amount is <b>{props.amount}</b></p>
}
ReactDom.render(
<Account total={20} amount={5000} />,
document.getElementById('root')
);
Even though the body of both looks similar, the latter becomes a component when we import React into the file. This is what makes it possible for us to use things like JSX and React hooks inside.
If we happened to import our preferred hook without importing React (which makes it a regular function), we will not be able to make use of the Hook we’ve imported as the Hook is accessible only in React component.
Call Hooks From Custom Hooks
A custom Hook is a JavaScript function whose name starts with use and that may call other Hooks. For example, useUserName is used below a custom Hook that calls the useState and useEffect hooks. It fetches data from an API, loops through the data, and calls setIsPresent() if the specific username it received is present in the API data.
We can then go on to reuse the functionality of this hook in other places where we need such in our application. In such places, except when needed, we don’t have to call useState or useEffect anymore.
By following this rule, we ensure that all stateful logic in a component is clearly visible from its source code.
Function Component Vs Class Component In Hooks
Let’s take a brief look at class components and functional components (with Hooks), before diving into the few Hooks best practices.
The simplest way to define a component in React is to write a JavaScript function that returns a React element:
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
The Welcome component accepts props which is an object that contains data and returns a React element. We can then import and render this component in another component.
The class component uses a programming methodology called Encapsulation which basically means that everything relevant to the class component will live within it. Life-cycle methods (constructors, componentDidMount(), render, and so on) give components a predictable structure.
Encapsulation is one of the fundamentals of OOP (Object-Oriented Programming). It refers to the bundling of data within the methods that operate on that data, and is used to hide the values or state of a structured data object inside a class — preventing unauthorized parties’ direct access to them.
With Hooks, the composition of a component changes from being a combination of life-cycle Hooks — to functionalities with some render at the end.
Function Component
The example below shows how custom Hooks can be used in a functional component (without showcasing what the body is). However, what it does or can do is not limited. It could be instantiating state variables, consuming contexts, subscribing the component to various side effects — or all of the above if you’re using a custom hook!
function {
useHook{...};
useHook{...};
useHook{...};
return (
...
);
}
Class Component
A class component requires you to extend from React.Component and create a render function which returns a React element. This requires more code but will also give you some benefits.
There are some benefits you get by using functional components in React:
It will get easier to separate container and presentational components because you need to think more about your component’s state if you don’t have access to setState() in your component.
Functional components are much easier to read and test because they are plain JavaScript functions without state or lifecycle-hooks.
You end up with less code.
The React team mentioned that there may be a performance boost for functional components in future React versions.
This leads to the first best practice when using React Hooks.
Hooks Best Practices
There are some best practices in writing Hooks the right and effective way as below:
Simplify Your Hooks
Organize And Structure Your Hooks
Use React Hooks Snippets
Put Hooks Rules into Consideration
1. Simplify Your Hooks
Keeping React Hooks simple will give us the power to effectively control and manipulate what goes on in a component throughout its lifetime. Avoid writing custom Hooks as much as possible; we can inline a useState() or useEffect() instead of creating our own hook.
If we find ourself making use of a bunch of custom Hooks that are related in functionality, we can create a custom hook that acts as a wrapper for these. Let’s take a look at two different functional components with hooks below.
Functional Component v1
function {
useHook(...);
useHook(...);
useHook(...);
return(
<div>...</div>
);
}
Functional Component v2
function {
useCustomHook(...);
useHook(...);
useHook(...);
return(
<div>...</div>
);
}
v2 is a better version because it keeps the hook simple and all other useHooks are inline accordingly. This allows us to create functionality that can be reused across different components and also gives us more power to control and manipulate our components effectively. Instead of adopting v1 in which our components are littered with Hooks, we should make use of v2 which will make debugging easy and our code cleaner.
2. Organize And Structure Your Hooks
One of the advantages of React Hooks is the ability to write less code that is easy to read. In some cases, the amount of useEffect() and useState() can still be confusing. When we keep our component organized it will help in readability and keep the flow of our components consistent and predictable. If our custom Hooks are too complicated, we can always break them down to sub-custom Hooks. Extract the logic of our component to custom Hooks to make our code readable.
3. Use React Hooks Snippets
React Hooks Snippets is a Visual Studio Code extension to make React Hooks easier and faster. Currently, five hooks are supported:
useState()
useEffect()
useContext()
useCallback()
useMemo()
There are two ways (Command and Extension Marketplace) we can add React Hooks snippets to our project:
4. Put Hooks Rules into Consideration
Endeavor to always put the two rules of Hooks we learned earlier into consideration while working with React Hooks.
Only call your Hooks at the top level. Don’t call Hooks inside loops, conditions or nested functions.
Always call Hooks from React function components or from custom Hooks, don’t call Hooks from regular JavaScript functions.
The ESlint plugin called eslint-plugin-react-hooks enforces these two rules, we can add this plugin to your project if we’d like it as we explain above in rules of hooks section.
Best practices have not been fully resolved because Hooks are still relatively new. So adoption should be taken with precaution one would take in adopting in any early technology. With that in mind, Hooks are the way for the future of React.
That’s all about in this article.
Conclusion
In this article, We understood about the two most important rules of React Hooks and how to effectively think in Hooks. We looked at functional components and some best practices in writing Hooks the right and effective way. As brief as the rules are, it’s important to make them our guiding compass when writing rules. If we are prone to forget it, we can make use of the ESLint plugin to enforce it.
Thanks for reading ! I hope you enjoyed and learned about the Hook Concepts in ReactJS. Reading is one thing, but the only way to master it is to do it yourself.
Please follow and subscribe us on this blog and and support us in any way possible. Also like and share the article with others for spread valuable knowledge.
If you have any comments, questions, or think I missed something, feel free to leave them below in the comment box.
Hello Readers, CoolMonkTechie heartily welcomes you in this article.
In this article, we will understand about Virtual DOM Working structure in ReactJS. We will analyse below topics to understand the Virtual DOM Concepts in ReactJS.
What is Real DOM ?
What Issues in Real DOM ?
What is Virtual DOM?
How Virtual DOM helps to solve issue?
React Elements Vs React Components in Virtual DOM
Real DOM Vs Virtual DOM
A famous quote about learning is :
” An investment in knowledge pays the best interest.”
So Let’s begin.
Real DOM
DOM stands for Document Object Model and is an abstraction of a structured text. For web developers, this text is an HTML code, and the DOM is simply called HTML DOM. Elements of HTML become nodes in the DOM.
So, while HTML is a text, the DOM is an in-memory representation of this text.
“Compare it to a process being an instance of a program. You can have multiple processes of the same one program, just like you can have multiple DOMs of the same HTML (e.g. the same page loaded on many tabs). “
The HTML DOM provides an interface (API) to traverse and modify the nodes. It contains methods like getElementById or removeChild. We usually use JavaScript language to work with the DOM, because… Well, nobody knows why :).
So, whenever we want to dynamically change the content of the web page, we modify the DOM:
#!javascript
var item = document.getElementById("myLI");
item.parentNode.removeChild(item);
document is an abstraction of the root node, while getElementById, parentNode and removeChild are methods from HTML DOM API.
Issues
The HTML DOM is always tree-structured – which is allowed by the structure of HTML document. This is cool because we can traverse trees fairly easily. Unfortunately, easily doesn’t mean quickly here.
The DOM trees are huge nowadays. Since we are more and more pushed towards dynamic web apps (Single Page Applications – SPAs), we need to modify the DOM tree incessantly and a lot. And this is a real performance and development pain.
Consider a DOM made of thousands of divs. Remember, we are modern web developers, our app is very Specific. We have lots of methods that handle events – clicks, submits, type-ins… A typical jQuery-like event handler looks like this:
find every node interested on an event
update it if necessary
Which has two problems:
It’s hard to manage. Imagine that you have to tweak an event handler. If you lost the context, you have to dive really deep into the code to even know what’s going on. Both time-consuming and bug-risky.
It’s inefficient. Do we really need to do all this findings manually? Maybe we can be smarter and tell in advance which nodes are to-be-updated?
Once again, React comes with a helping hand. The solution to problem 1 is declaratives. Instead of low-level techniques like traversing the DOM tree manually, you simple declare how a component should look like. React does the low-level job for you – the HTML DOM API methods are called under the hood. React doesn’t want you to worry about it – eventually, the component will look like it should.
But this doesn’t solve the performance issue. And this is exactly where the Virtual DOM comes into action.
Virtual DOM
In React, for every DOM object, there is a corresponding “virtual DOM object.” A virtual DOM object is a representation of a DOM object, like a lightweight copy.
A virtual DOM object has the same properties as a real DOM object, but it lacks the real thing’s power to directly change what’s on the screen.
A virtual DOM is a lightweight JavaScript object which originally is just the copy of the real DOM. It is a node tree that lists the elements, their attributes and content as Objects and their properties. React’s render function creates a node tree out of the React components. It then updates this tree in response to the mutations in the data model which is caused by various actions done by the user or by the system.
Manipulating the DOM is slow. Manipulating the virtual DOM is much faster, because nothing gets drawn onscreen. Think of manipulating the virtual DOM as editing a blueprint, as opposed to moving rooms in an actual house.
How it helps
When you render a JSX element, every single virtual DOM object gets updated.
This sounds incredibly inefficient, but the cost is insignificant because the virtual DOM can update so quickly.
Once the virtual DOM has updated, then React compares the virtual DOM with a virtual DOM snapshot that was taken right before the update.
By comparing the new virtual DOM with a pre-update version, React figures out exactly which virtual DOM objects have changed. This process is called “diffing.”
Once React knows which virtual DOM objects have changed, then React updates those objects, and only those objects, on the real DOM. In our example from earlier, React would be smart enough to rebuild your one checked-off list-item, and leave the rest of your list alone.
This makes a big difference! React can update only the necessary parts of the DOM. React’s reputation for performance comes largely from this innovation.
In summary, here’s what happens when you try to update the DOM in React:
The entire virtual DOM gets updated.
The virtual DOM gets compared to what it looked like before you updated it. React figures out which objects have changed.
The changed objects, and the changed objects only, get updated on the real DOM.
Changes on the real DOM cause the screen to change.
ReactElement Vs ReactComponent
When we are talking about the virtual DOM, it’s important to see the difference between these two.
ReactElement
This is the primary type in React. React docs say:
” A ReactElement is a light, stateless, immutable, virtual representation of a DOM Element.“
ReactElements lives in the virtual DOM. They make the basic nodes here. Their immutability makes them easy and fast to compare and update. This is the reason of great React performance.
What can be a ReactElement? Almost every HTML tag – div, table, strong.
Once defined, ReactElements can be render into the “real” DOM. This is the moment when React ceases to control the elements. They become slow, boring DOM nodes:
#!javascript
var root = React.createElement('div');
ReactDOM.render(root, document.getElementById('example'));
// If you are surprised by the fact that `render`
// comes from `ReactDOM` package, see the Post Script.
JSX compiles HTML tags to ReactElements. So this is equivalent to the above:
#!javascript
var root = <div />;
ReactDOM.render(root, document.getElementById('example'));
Once again – ReactElements are the basic items in React virtual DOM. However, they are stateless, therefore don’t seem to be very helpful for us, the programmers. We would rather work on the class-like pieces of HTML, with kind-of-variables and kind-of-constants – don’t we? And here we come to…
ReactComponent
What differs ReactComponent from ReactElement is – ReactComponents are stateful.
We usually use React.createClass method to define one:
#!javascript
var CommentBox = React.createClass({
render: function() {
return (
<div className="commentBox">
Hello, world! I am a CommentBox.
</div>
);
}
});
Your HTML-like blocks returned from render method can have a state. And the best thing is whenever the state changes, the component is re-rendered:
ReactComponents turned out to be a great tool for designing dynamic HTML. They don’t have the access to the virtual DOM, but they can be easily converted to ReactElements:
#!javascript
var element = React.createElement(MyComponent);
// or equivalently, with JSX
var element = <MyComponent />;
What makes the difference?
ReactComponents are great. They are easy to manage. But they have no access to the virtual DOM – and we would like to do as much as possible there.
Whenever a ReactComponent is changing the state, we want to make as little changes to the “real” DOM as possible. So this is how React deals with it. The ReactComponent is converted to the ReactElement. Now the ReactElement can be inserted to the virtual DOM, compared and updated fast and easily. How exactly – well, that’s the job of the diff algorithm. The point is – it’s done faster than it would be in the “regular” DOM.
When React knows the diff – it’s converted to the low-level (HTML DOM) code, which is executed in the DOM. This code is optimised per browser.
Real DOM Vs Virtual DOM
Now we can say about the difference between Real DOM and Virtual DOM that :
Real DOM is a language-neutral interface allowing programs and scripts to dynamically access and update multiple objects like content, structure, and style of a document. while Virtual DOM is a collection of modules designed to provide a declarative way to represent the DOM for an application.
The Real DOM represents the document as nodes and objects, while A virtual DOM object is a representation of a DOM object, like a lightweight copy.
Real DOM is an object-oriented representation of a web page, modified with a scripting language like JavaScript , while Virtual DOM is ideal for mobile-first applications.
Real DOM updates Slow while Virtual DOM updates faster.
Real DOM can directly update HTML, while Virtual DOM can’t directly update HTML.
Real DOM creates a new DOM if element updates, while Virtual DOM updates the JSX if element updates.
With Real DOM, DOM manipulation is very expensive, while DOM manipulation is very easy with Virtual DOM.
Real DOM includes Too much of memory wastage, while Virtual DOM includes no memory wastage.
That’s all about in this article.
Conclusion
In this article, We understood about about Virtual DOM Working structure in ReactJS.
Thanks for reading ! I hope you enjoyed and learned about the Virtual DOM concepts in ReactJS. Reading is one thing, but the only way to master it is to do it yourself.
Please follow and subscribe us on this blog and and support us in any way possible. Also like and share the article with others for spread valuable knowledge.
If you have any comments, questions, or think I missed something, feel free to leave them below in the comment box.
Hello Readers, CoolMonkTechie heartily welcomes you in A Short Note Series (Unit Vs Integration Vs End To End Testing).
In this note series, we will understand about the difference between unit testing, integration testing and End to end testing in React Testing Framework.
So Let’s begin.
Unit Testing
Unit Testing is an isolated part of your app, usually done in combination with shallow rendering.
Example: A component renders with the default props.
Integration Testing
IntegrationTesting if different parts work or integrate with each other. Usually done with mounting or rendering a component.
Example: Test if a child component can update context state in a parent.
End To End Testing
It stands for end to end (e to e testing) . Usually a multi step test combining multiple unit and integration tests into one big test. Usually very little is mocked or stubbed. Tests are done in a simulated browser, there may or may not be a UI while the test is running.
Example: Testing an entire authentication flow.
Conclusion
In this note series, We understood about the difference between unit testing, integration testing and End to end testing in React Testing Framework.
Thanks for reading ! I hope you enjoyed and learned about Unit Testing Vs Integration Testing Vs End to end Testing Concepts in React Testing Framework. Reading is one thing, but the only way to master it is to do it yourself.
Please follow and subscribe to the blog and support us in any way possible. Also like and share the article with others for spread valuable knowledge.
You can find Other articles of CoolmonkTechie as below link :
Hello Readers, CoolMonkTechie heartily welcomes you in A Short Note Series.
In this note series, we will discuss about difference between Shallow and Mount in React Testing.
So Let’s begin.
Mount
Mount actually executes the html, css and js code like a browser would, but does so in a simulated way. It is “headless” for example, meaning it doesn’t render or paint anything to a UI, but acts as a simulated web browser and executes the code in the background.
Not spending time painting anything to the UI makes your tests much faster. However mount tests are still much slower than shallow tests.
This is why you unmount or cleanup the component after each test, because it’s almost a live app and one test will affect another test.
Mount/render is typically used for integration testing.
Shallow
Shallow is used for unit testing. Shallow rendering only renders the single component we are testing. It does not render child components. This allows us to test our component in isolation.
When writing unit tests for React, shallow rendering can be helpful. Shallow rendering lets you render a component “one level deep” and assert facts about what its render method returns, without worrying about the behavior of child components, which are not instantiated or rendered. This does not require a DOM.
Conclusion
In this note series, We understood about the difference between Shallow and Mount in React Testing. So we conclude that
Shallow() tests components in isolation from the child components they render while mount() goes deeper and tests a component’s children.
Mount(<Component />) for Full DOM rendering is ideal for use cases where you have components that may interact with DOM apis, or may require the full lifecycle in order to fully test the component (ie, componentDidMount etc.) while shallow(<Component />) for Shallow rendering is useful to constrain yourself to testing a component as a unit, and to ensure that your tests aren’t indirectly asserting on behavior of child components.
Mount/render is typically used for integration testing while Shallow is used for unit testing.
Thanks for reading ! I hope you enjoyed and learned about Shallow and Mount Concepts in React Testing. Reading is one thing, but the only way to master it is to do it yourself.
Please follow and subscribe us on this blog and and support us in any way possible. Also like and share the article with others for spread valuable knowledge.
If you have any comments, questions, or think I missed something, feel free to leave them below in the comment box.
Hello Readers, CoolMonkTechie heartily welcomes you in this article.
In this article, We will learn about nine useful criteria of A React Component in ReactJS. We want to know how React embraces component-based architecture. We can compose complex user interfaces from smaller pieces, take advantage of components reusability and abstracted DOM manipulations.
We know about React : “Component-based development is productive: a complex system is built from specialized and easy to manage pieces. Yet only well designed components ensure composition and reusability benefits.“
Despite the application complexity, we hurry to meet the deadlines and unexpectedly changing requirements, we must constantly walk on the thin line of architectural correctness. Make our components decoupled, focused on a single task, well tested.
Luckily, reliable components have common characteristics. We will discuss below 9 useful criterias with details.
Single responsibility
Encapsulated
Composable
Reusable
Pure or Almost Pure
Testable and Tested
Meaningful
Do Continuous Improvement
Reliability
A famous quote about learning is :
” Try to learn something about everything and everything about something.”
So Let’s begin.
When writing a React application, We need regularly ask questions ourself:
How to correctly structure the component?
At what point a big component should split into smaller components?
How to design a communication between components that prevents tight coupling?
Because Technical debt making progressively hard to modify existing or create new functionality. This will happen when write big components with many responsibilities, tightly couple components, forget about unit tests. These increase technical debt.
So we can solve this issue with the use of a reliable react component criterias. So we look these criterias one by one.
1. Single responsibility
A fundamental rule to consider when writing React components is the single responsibility principle.
” A component has a single responsibility when it has one reason to change. “
Single responsibility principle (abbreviated SRP) requires a component to have one reason to change.
A component has one reason to change when it implements one responsibility, or simpler when it does one thing.
A responsibility is either to render a list of items, or to show a date picker, or to make an HTTP request, or to draw a chart, or to lazy load an image, etc. Our component should pick only one responsibility and implement it. When we modify the way component implements its responsibility (e.g. a change to limit the number of items for render a list of items responsibility) – it has one reason to change.
Why is it important to have only one reason to change? Because component’s modification becomes isolated and under control.
Having one responsibility restricts the component size and makes it focused on one thing. A component focused on one thing is convenient to code, and later modify, reuse and test.
Let’s follow a few examples.
Example 1 :- A component fetches remote data, correspondingly it has one reason to change when fetch logic changes.
A reason to change happens when:
The server URL is modified
The response format is modified
You want to use a different HTTP requests library
Or any modification related to fetch logic only.
Example 2 :- A table component maps an array of data to a list of row components, as result having one reason to change when mapping logic changes.
A reason to change occurs when:
We have a task to limit the number of rendered row components (e.g. display up to 25 rows)
We’re asked to show a message “The list is empty” when there are no items to display
Or any modification related to mapping of array to row components only.
Does our component have many responsibilities?If the answer is yes, split the component into chunks by each individual responsibility.
An alternative reasoning about the single responsibility principle says to create the component around a clearly distinguishable axis of change. An axis of change attracts modifications of the same meaning.
In the previous 2 examples, the axis of change were fetch logic and mapping logic.
Units written at early project stage will change often until reaching the release stage. These change often components are required to be easily modifiable in isolation: a goal of the SRP.
Case study: make component have one responsibility
Imagine a component that makes an HTTP request to a specialized server to get the current weather. When data is successfully fetched, the same component uses the response to display the weather:
When dealing with alike situations, ask ourself: do we have to split the component into smaller pieces? The question is best answered by determining how component might change according to its responsibilities.
The weather component has 2 reasons to change:
Fetch logic in componentDidMount(): server URL or response format can be modified
Weather visualization in render(): the way component displays the weather can change several times
The solution is to divide <Weather> in 2 components: each having one responsibility. Let’s name the chunks <WeatherFetch> and <WeatherInfo>.
First component <WeatherFetch> is responsible for fetching the weather, extracting response data and saving it to state. It has one fetch logic reason to change:
import axios from 'axios';
// Solution: Make the component responsible only for fetching
class WeatherFetch extends Component {
constructor(props) {
super(props);
this.state = { temperature: 'N/A', windSpeed: 'N/A' };
}
render() {
const { temperature, windSpeed } = this.state;
return (
<WeatherInfo temperature={temperature} windSpeed={windSpeed} />
);
}
componentDidMount() {
axios.get('http://weather.com/api').then(function(response) {
const { current } = response.data;
this.setState({
temperature: current.temperature,
windSpeed: current.windSpeed
});
});
}
}
What benefits brings such structuring?
For instance, we would like to use async/await syntax instead of promises to get the response from server. This is a reason to change related to fetch logic:
// Reason to change: use async/await syntax
class WeatherFetch extends Component {
// ..... //
async componentDidMount() {
const response = await axios.get('http://weather.com/api');
const { current } = response.data;
this.setState({
temperature: current.temperature,
windSpeed: current.windSpeed
});
}
}
Because <WeatherFetch> has one fetch logic reason to change, any modification of this component happens in isolation. Using async/await does not affect directly the way weather is displayed.
Then <WeatherFetch> renders <WeatherInfo>. The latter is responsible only for displaying the weather, having one visual reason to change:
// Solution: Make the component responsible for displaying the weather
function WeatherInfo({ temperature, windSpeed }) {
return (
<div className="weather">
<div>Temperature: {temperature}°C</div>
<div>Wind: {windSpeed} km/h</div>
</div>
);
}
Let’s change <WeatherInfo> that instead of "Wind: 0 km/h" display "Wind: calm". That’s a reason to change related to visual display of weather:
Again, this modification of <WeatherInfo> happens in isolation and does not affect <WeatherFetch> component.
<WeatherFetch> and <WeatherInfo> have their own one responsibility. A change of one component has small effect on the other one. That’s the power of single responsibility principle: modification in isolation that affects lightly and predictability other components of the system.
2. Encapsulated
“An encapsulated component provides props to control its behavior while not exposing its internal structure. “
Coupling is a system characteristic that determines the degree of dependency between components.
Based on the degree of components dependence, 2 coupling types are distinguishable:
Loose couplinghappens when the application components have little or no knowledge about other components.
Tight coupling happens when the application components know a lot of details about each other.
Loose coupling is the goal when designing application’s structure and the relationship between components.
Loose coupling leads to the following benefits:
Allow making changes in one area of the application without affecting others
Any component can be replaced with an alternative implementation
Enables components reusability across the application, thus favoring Don’t repeat yourself principle
Independent components are easier to test, increasing the application code coverage
Contrary, a tightly coupled system looses the benefits described above. The main drawback is the difficulty to modify a component that is highly dependent on other components. Even a single modification might lead to a cascade of dependency echo modifications.
Encapsulation, or Information Hiding, is a fundamental principle of how to design components, and is the key to loose coupling.
Information hiding
A well encapsulated component hides its internal structure and provides a set of props to control its behavior.
Hiding internal structure is essential. Other components are not allowed to know or rely on the component’s internal structure or implementation details.
A React component can be functional or class based, define instance methods, setup refs, have state or use lifecycle methods. These implementation details are encapsulated within the component itself, and other components shouldn’t know anything about these details.
Units that precisely hide their internal structure are less dependent on each other. Lowering the dependency degree brings the benefits of loose coupling.
Communication
Details hiding is a restriction that isolates the component. Nevertheless, we need a way to make components communicate. So welcome the props.
Props are meant to be plain, raw data that are component’s input.
A prop is recommended to be a primitive type (e.g. string, number, boolean):
<Message text="Hello world!" modal={false} />;
When necessary use a complex data structure like objects or arrays:
To avoid breaking encapsulation, watch out the details passed through props. A parent component that sets child props should not expose any details about its internal structure. For example, it’s a bad decision to transmit using props the whole component instance or refs.
Accessing global variables is another problem that negatively affects encapsulation.
Case study: encapsulation restoration
Component’s instance and state object are implementation details encapsulated inside the component. Thus a certain way to break the encapsulation is to pass the parent instance for state management to a child component.
Let’s study such a situation.
A simple application shows a number and 2 buttons. First button increases and second button decreases the number. The application consists of two components: <App> and <Controls>.
<App> holds the state object that contains the modifiable number as a property, and renders this number:
<Controls> renders the buttons and attaches click event handlers to them. When user clicks a button, parent component state is updated (updateNumber() method) by increasing +1 or decreasing -1 the displayed number:
The first problem is <App>’s broken encapsulation, since its internal structure spreads across the application. <App> incorrectly permits <Controls> to update its state directly.
Consequently, the second problem is that <Controls> knows too many details about its parent <App>. It has access to parent instance, knows that parent is a stateful component, knows the state object structure (number property) and knows how to update the state.
The broken encapsulation couples <App> and <Controls> components.
A troublesome outcome is that <Controls> would be complicated to test and reuse. A slight modification to structure of <App> leads to cascade of modifications to <Controls> (and to alike coupled components in case of a bigger application).
The solution is to design a convenient communication interface that respects loose coupling and strong encapsulation. Let’s improve the structure and props of both components in order to restore the encapsulation.
Only the component itself should know its state structure. The state management of <App> should move from <Controls> (updateNumber() method) in the right place: <App> component.
Later, <App> is modified to provide <Controls> with props onIncrease and onDecrease. These are simple callbacks that update <App> state:
Now <Controls> receives callbacks for increasing and decreasing the number. Notice the decoupling and encapsulation restoration moment: <Controls> has no longer the need to access parent instance and modify <App> state directly.
Moreover <Controls> is transformed into a functional component:
// Solution: Use callbacks to update parent state
function Controls({ onIncrease, onDecrease }) {
return (
<div className="controls">
<button onClick={onIncrease}>Increase</button>
<button onClick={onDecrease}>Decrease</button>
</div>
);
}
<App> encapsulation is now restored. The component manages its state by itself, as it should be.
Furthermore <Controls> no longer depends on <App> implementation details. onIncrease and onDecrease prop functions are called when corresponding button is clicked, and <Controls> does not know (and should not know) what happens inside those functions.
<Controls> reusability and testability significantly increased.
The reuse of <Controls> is convenient because it requires only callbacks, without any other dependencies. Testing is also handy: just verify whether callbacks are executed on buttons click.
3. Composable
“A composable component is created from the composition of smaller specialized components.”
Composition is a way to combine components to create a bigger (composed) component. Composition is the heart of React.
Fortunately, composition is easy to understand. Take a set of small pieces, combine them, and create a bigger thing.
Let’s look at a common frontend application composition pattern. The application is composed of a header at the top, footer at the bottom, sidebar on the left and payload content in the middle:
The application demonstrates how well composition builds the application. Such organization is expressive and open for understanding.
React composes components expressively and naturally. The library uses a declarative paradigm that doesn’t suppress the expressiveness of composition. The following components render the described application:
<Application> is composed of <Header>, <Sidebar>, <Content> and <Footer>. <Sidebar> has one component <Menu>, as well as <Content> has one <Article>.
How does composition relate with single responsibility and encapsulation?
” Single responsibility principle describes how to split requirements into components, encapsulation describes how to organize these components, and composition describes how to glue the whole system back. “
Composition benefits
Single responsibility
An important aspect of composition is the ability to compose complex components from smaller specialized components. This divide and conquer approach helps an authority component conform to single responsibility principle.
Recall the previous code snippet. <Application> has the responsibility to render the header, footer, sidebar and main regions.
Makes sense to divide this responsibility into four sub-responsibilities, each of which is implemented by specialized components <Header>, <Sidebar>, <Content> and <Footer>. Later composition glues back <Application> from these specialized components.
Now comes up the benefit. Composition makes <Application> conform to single responsibility principle, by allowing its children to implement the sub-responsibilities.
Reusability
Components using composition can reuse common logic. This is the benefit of reusability.
For instance, components <Composed1> and <Composed2> share common code:
const instance1 = (
<Composed1>
/* Specific to Composed1 code... */
/* Common code... */
</Composed1>
);
const instance2 = (
<Composed2>
/* Common code... */
/* Specific to Composed2 code... */
</Composed2>
);
Since code duplication is a bad practice, how to make components reuse common code?
Firstly, encapsulate common code in a new component <Common>. Secondly, <Composed1> and <Composed2> should use composition to include <Common>, fixing code duplication:
Reusable components favor Don’t repeat yourself (DRY) principle. This beneficial practice saves efforts and time.
Flexibility
In React a composable component can control its children, usually through children prop. This leads to another benefit of flexibility.
For example, a component should render a message depending on user’s device. Use composition’s flexibility to implement this requirement:
function ByDevice({ children: { mobile, other } }) {
return Utils.isMobile() ? mobile : other;
}
<ByDevice>{{
mobile: <div>Mobile detected!</div>,
other: <div>Not a mobile device</div>
}}</ByDevice>
<ByDevice> composed component renders the message "Mobile detected!" for a mobile, and "Not a mobile device" for other devices.
Efficiency
User interfaces are composable hierarchical structures. Thus composition of components is an efficient way to construct user interfaces.
4. Reusable
“A reusable component is written once but used multiple times.”
Imagine a fantasy world where software development is mostly reinventing the wheel.
When coding, we can’t use any existing libraries or utilities. Even across the application we can’t use code that we already wrote.
In such environment, would it be possible to write an application in a reasonable amount of time? Definitely not.
Welcome reusability. Make things work, not reinvent how they work.
Reuse across application
According to Don’t repeat yourself (DRY) principle, every piece of knowledge must have a single, unambiguous, authoritative representation within a system. The principle advises to avoid repetition.
Code repetition increases complexity and maintenance efforts without adding significant value. An update of the logic forces you to modify all its clones within the application.
Repetition problem is solved with reusable components. Write once and use many times: efficient and time saving strategy.
However we don’t get reusability property for free. A component is reusable when it conforms to single responsibility principle and has correct encapsulation.
Conforming to single responsibility is essential:
“Reuse of a component actually means the reuse of its responsibility implementation.”
Components that have only one responsibility are the easiest to reuse.
But when a component incorrectly has multiple responsibilities, its reusage adds a heavy overhead. We want to reuse only one responsibility implementation, but also we get the unneeded implementation of out of place responsibilities.
We want a banana, and we get a banana, plus all the jungle with it.
Correct encapsulation creates a component that doesn’t stuck with dependencies. Hidden internal structure and focused props enable the component to fit nicely in multiple places where it’s about to be reused.
Reuse of 3rd party libraries
A regular working day. We’ve just read the task to add a new feature to the application. Before firing up the text editor, hold on for a few minutes…
There’s a big chance that the problem we start working on is already solved. Due to React’s popularity and great open source community, it worth searching for an existing solution.
Good libraries positively affect architectural decisions and advocate best practices. In my experience, the top influencers are react-router and redux.
react-router uses declarative routing to structure a Single Page Application. Associate a URL path with your component using <Route>. Then router will render the component for you when user visits the matched URL.
redux and react-redux HOC introduce unidirectional and predictable application state management. It extracts async and impure code (like HTTP requests) out of components, favoring single responsibility principle and creating pure or almost-pure components.
To be sure that a 3rd party library is worth using, here’s we need to verify checklist details:
Documentation: verify whether the library has meaningful readme.md file and detailed documentation
Tested: a sign of trustworthy library is high code coverage
Maintenance: see how often the library author creates new features, fixes bugs and generally maintains the library.
5. Pure or Almost-pure
“A pure component always renders same elements for same prop values.”
“An almost-pure component always renders same elements for same prop values, and can produce a side effect.”
In functional programming terms, a pure function always returns the same output for given the same input. Let’s see a simple pure function:
function sum(a, b) {
return a + b;
}
sum(5, 10); // => 15
For given two numbers, sum() function always returns the same sum.
A function becomes impure when it returns different output for same input. It can happen because the function relies on global state. For example:
let said = false;
function sayOnce(message) {
if (said) {
return null;
}
said = true;
return message;
}
sayOnce('Hello World!'); // => 'Hello World!'
sayOnce('Hello World!'); // => null
sayOnce('Hello World!') on first call returns 'Hello World!'.
Even when using same argument 'Hello World!', on later invocations sayOnce() returns null. That’s the sign of an impure function that relies on a global state: said variable.
sayOnce() body has a statement said = true that modifies the global state. This produces a side effect, which is another sign of impure function.
Consequently, pure functions have no side effects and don’t rely on global state. Their single source of truth are parameters. Thus pure functions are predictable and determined, are reusable and straightforward to test.
React components should benefit from pure property. Given the same prop values, a pure component (not to be confused with React.PureComponent) always renders the same elements. Let’s take a look:
function Message({ text }) {
return <div className="message">{text}</div>;
}
<Message text="Hello World!" />
// => <div class="message">Hello World</div>
You are guaranteed that <Message> for the same text prop value renders the same elements.
It’s not always possible to make a component pure. Sometimes we have to ask the environment for information, like in the following case:
<InputField> stateful component doesn’t accept any props, however renders different output depending on what user types into the input. <InputField> has to be impure, because it accesses the environment through input field.
Impure code is a necessary evil. Most of the applications require global state, network requests, local storage and alike. What we can do is isolate impure code from pure, a.k.a. apply purification on our components.
Isolated impure code explicitly shows it has side effects, or rely on global state. Being in isolation, impure code has less unpredictability effect on the rest of the system.
Let’s detail into purification examples.
Case study: purification from global variables
We don’t like global variables. They break encapsulation, create unpredictable behavior and make testing difficult.
Global variables can be used as mutable or immutable (read-only) objects.
Mutating global variables create uncontrolled behavior of components. Data is injected and modified at will, confusing reconciliation process. This is a mistake.
If we need a mutable global state, the solution is a predictable application state management. Consider using Redux.
An immutable (or read-only) usage of globals is often application’s configuration object. This object contains the site name, logged-in user name or any other configuration information.
The following statement defines a configuration object that holds the site name:
export const globalConfig = {
siteName: 'Animals in Zoo'
};
Next, <Header> component renders the header of an application, including the display of site name "Animals in Zoo":
import { globalConfig } from './config';
export default function Header({ children }) {
const heading =
globalConfig.siteName ? <h1>{globalConfig.siteName}</h1> : null;
return (
<div>
{heading}
{children}
</div>
);
}
<Header> component uses globalConfig.siteName to render site name inside a heading tag <h1>. When site name is not defined (i.e. null), the heading is not displayed.
The first to notice is that <Header> is impure. Given same value of children, the component returns different results because of globalConfig.siteName variations:
// globalConfig.siteName is 'Animals in Zoo'
<Header>Some content</Header>
// Renders:
<div>
<h1>Animals in Zoo</h1>
Some content
</div>
or
// globalConfig.siteName is `null`
<Header>Some content</Header>
// Renders:
<div>
Some content
</div>
The second problem is testing difficulties. To test how component handles null site name, we have to modify the global variable globalConfig.siteName = null manually:
import assert from 'assert';
import { shallow } from 'enzyme';
import { globalConfig } from './config';
import Header from './Header';
describe('<Header />', function() {
it('should render the heading', function() {
const wrapper = shallow(
<Header>Some content</Header>
);
assert(wrapper.contains(<h1>Animals in Zoo</h1>));
});
it('should not render the heading', function() {
// Modification of global variable:
globalConfig.siteName = null;
const wrapper = shallow(
<Header>Some content</Header>
);
assert(appWithHeading.find('h1').length === 0);
});
});
The modification of global variable globalConfig.siteName = null for sake of testing is hacky and uncomfortable. It happens because <Heading> has a tight dependency on globals.
To solve such impurities, rather than injecting globals into component’s scope, make the global variable an input of the component.
Let’s modify <Header> to accept one more prop siteName. Then wrap the component with defaultProps() higher order component (HOC) from recompose library. defaultProps() ensures fulfilling the missing props with default values:
<Header> becomes a pure functional component, and does not depend directly on globalConfig variable. The pure version is a named export: export function Header() {...}, which is useful for testing.
At the same time, the wrapped component with defaultProps({...}) sets globalConfig.siteName when siteName prop is missing. That’s the place where impure code is separated and isolated.
Let’s test the pure version of <Header> (remember to use a named import):
import assert from 'assert';
import { shallow } from 'enzyme';
import { Header } from './Header'; // Import the pure Header
describe('<Header />', function() {
it('should render the heading', function() {
const wrapper = shallow(
<Header siteName="Animals in Zoo">Some content</Header>
);
assert(wrapper.contains(<h1>Animals in Zoo</h1>));
});
it('should not render the heading', function() {
const wrapper = shallow(
<Header siteName={null}>Some content</Header>
);
assert(appWithHeading.find('h1').length === 0);
});
});
This is great. Unit testing of pure <Header> is straightforward. The test does one thing: verify whether the component renders the expected elements for a given input. No need to import, access or modify global variables, no side effects magic.
Well designed components are easy to test , which is visible in case of pure components.
6. Testable and Tested
“A tested component is verified whether it renders the expected output for a given input.“
“A testable component is easy to test. “
How to be sure that a component works as expected? We can say: “We manually verify how it works.”
If we plan to manually verify every component modification, sooner or later we’re going to skip this tedious task. Sooner or later small defects are going to make through.
That’s why is important to automate the verification of components: do unit testing. Unit tests make sure that our components are working correctly every time we make a modification.
Unit testing is not only about early bugs detection. Another important aspect is the ability to verify how well components are built architecturally.
The following statement I find especially important:
“A component that is untestable or hard to test is most likely badly designed. “
A component is hard to test because it has a lot of props, dependencies, requires mockups and access to global variables: that’s the sign of a bad design.
When the component has weak architectural design, it becomes untestable. When the component is untestable, we simply skip writing unit tests: as result it remains untested.
In conclusion, the reason why many applications are untested is incorrectly designed components. Even if we want to test such an application, we can’t.
Case study: testable means well designed
Let’s test 2 versions of <Controls> from the encapsulation point.
The following code tests <Controls> version that highly depends on the parent’s component structure:
<Controls> is complicated to test, since it relies on parent’s component implementation details.
The test scenario requires an additional component <Temp>, which emulates the parent. It permits to verify whether <Controls> modifies correctly parent’s state.
When <Controls> is independent of parent details, testing is easier. Let’s test the version with correct encapsulation:
Strong encapsulation leads to easy and straightforward testing. And contrary a component with incorrect encapsulation is difficult to test.
Testability is a practical criteria to identify how well our components are structured.
7. Meaningful
“A meaningful component is easy to understand what it does.“
It’s hard underestimate the importance of readable code. How many times did we stuck with obscured code? We see the characters, but don’t see the meaning.
Developer spends most of the time reading and understanding code, than actually writing it. Coding activity is 75% of time understanding code, 20% of time modifying existing code and only 5% writing new source.
A slight additional time spent on readability reduces the understanding time for teammates and ourself in the future. The naming practice becomes important when the application grows, because understanding efforts increase with volume of code.
Reading meaningful code is easy. Nevertheless writing meaningfully requires clean code practices and constant effort to express ourself clearly.
Component naming
Pascal case
Component name is a concatenation of one or more words (mostly nouns) in pascal case. For instance <DatePicker>, <GridItem>, <Application>, <Header>.
Specialization
The more specialized a component is, the more words its name might contain.
A component named <HeaderMenu> suggests a menu in the header. A name <SidebarMenuItem> indicates a menu item located in sidebar.
A component is easy to understand when the name meaningfully implies the intent. To make this happen, often we have to use verbose names. That’s fine: more verbose is better than less clear.
Suppose we navigate some project files and identify 2 components: <Authors> and <AuthorsList>. Based on names only, can we conclude the difference between them? Most likely not.
To get the details, you have to open <Authors> source file and explore the code. After doing that, we realize that <Authors> fetches authors list from server and renders <AuthorsList> presentational component.
A more specialized name instead of <Authors> doesn’t create this situation. Better names are <FetchAuthors>, <AuthorsContainer> or <AuthorsPage>.
One word – one concept
A word represents a concept. For example, a collection of rendered items concept is represented by list word.
Pick one word per concept, then keep the relation consistent within the whole application. The result is a predicable mental mapping of words – concepts that you get used to.
Readability suffers when the same concept is represented by many words. For example, we define a component that renders a list of orders <OrdersList>, and another that renders a list of expenses <ExpensesTable>.
The same concept of a collection of rendered items is represented by 2 different words: list and table. There’s no reason to use different words for the same concept. It adds confusion and breaks consistency in naming.
Name the components <OrdersList> and <ExpensesList> (using list word) or <OrdersTable> and <ExpensesTable> (using table word). Use whatever word we feel is better, just keep it consistent.
Code comments
Meaningful names for components, methods and variables are enough for making the code readable. Thus, comments are mostly redundant.
Case study: write self-explanatory code
Common misuse of comments is explanation of inexpressive and obscured naming. Let’s see such case:
// <Games> renders a list of games
// "data" prop contains a list of game data
function Games({ data }) {
// display up to 10 first games
const data1 = data.slice(0, 10);
// Map data1 to <Game> component
// "list" has an array of <Game> components
const list = data1.map(function(v) {
// "v" has game data
return <Game key={v.id} name={v.name} />;
});
return <ul>{list}</ul>;
}
<Games
data=[{ id: 1, name: 'Mario' }, { id: 2, name: 'Doom' }]
/>
Comments in the above example clarify obscured code. <Games>, data, data1, v, magic number 10 are inexpressive and difficult to understand.
If we refactor the component to have meaningful props and variables, the comments are easily omitted:
Don’t explain ourself with comments. Write code that is self-explanatory and self-documenting.
Expressiveness stairs
We distinguish 4 expressiveness stairs of a component. The lower we move on the stairs, the more effort we need to understand the component.
We can understand what the component does from:
Reading name and props;
Consulting documentation;
Exploring the code;
Asking the author.
If name and props give enough information to integrate the component into application, that’s a solid expressiveness. Try to keep this high quality level.
Some components have complex logic, and even a good name can’t give the necessary details. It’s fine to consult the documentation.
If documentation is missing or doesn’t answer all the questions, We have to explore the code. Not the best option because of additional time spent, but it’s acceptable.
When exploring code doesn’t help decipher the component, the next step is asking component’s author for details. That’s definitely bad naming, and avoid going down to this step. Better ask the author to refactor the code, or refactor it yourself.
8. Do continuous improvement
“We then said that rewriting is the essence of writing. We pointed out that professional writers rewrite their sentences over and over and then rewrite what they have rewritten.”
To produce a quality text, we have to rewrite our sentence multiple times. Read the written, simplify confusing places, use more synonyms, remove clutter words – then repeat until we have an enjoyable piece of text.
Interestingly that the same concept of rewriting applies to designing the components.
Sometimes it’s hardly possible to create the right components structure at the first attempt. It happens because:
A tight deadline doesn’t allow spending enough time on system design
The initially chosen approach appears to be wrong
We’ve just found an open source library that solves the problem better
or any other reason.
Finding the right organization is a series of trials and reviews. The more complex a component is, the more often it requires verification and refactoring.
Does the component implement a single responsibility, is it well encapsulated, is it enough tested? If we can’t answer a certain yes, determine the weak part (by comparing against presented above 9 attributes) and refactor the component.
Pragmatically, development is a never stopping process of reviewing previous decisions and making improvements.
9. Reliability
Taking care of component’s quality requires effort and periodical review. It worth investment, since correct components are the foundation of a well designed system. Such system is easy to maintain and grow with complexity that increases linearly.
As result, development is relatively convenient at any project stage.
On the other hand, as system size increases, we might forget to plan and regularly correct the structure, decrease coupling. A naive approach to just make it work.
But after an inevitable moment when system becomes enough tightly coupled, fulfilling new requirements becomes exponentially complicated. We can’t control the code, the weakness of system controls us. A bug fix creates new bugs, a code update requires a cascade of related modifications.
How does the sad story end? We might throw away the current system and rewrite the code from scratch, or most likely continue eating the cactus. We’ve eaten plenty of cactuses, we’ve probably too, and it’s not the best feeling.
The solution is simple, yet demanding: write reliable components.
That’s all about in this article.
Conclusion
In this article, We understood about nine useful criteria of A React Component in ReactJS. The presented 9 characteristics suggest the same idea from different angles :
“A reliable component implements one responsibility, hides its internal structure and provides effective set of props to control its behavior.”
Single responsibility and encapsulation are the base of a solid design. We conclude that :
Single responsibility suggests to create a component that implements only one responsibility and has one reason to change.
Encapsulated component hides its internal structure and implementation details, and defines props to control the behavior and output.
Compositionstructures big and authority components. Just split them into smaller chunks, then use composition to glue the whole back, making complex simple.
Reusable components are the result of a well designed system. Reuse the code whenever you can to avoid repetition.
Side effects like network requests or global variables make components depend on environment. Make them pure by returning same output for same prop values.
Meaningfulcomponent naming and expressive code are the key to readability. Your code must be understandable and welcoming to read.
Testing is not only an automated way of detecting bugs. If you find a component difficult to test, most likely it’s incorrectly designed.
A quality, extensible and maintainable, thus successful application stands on shoulders of reliable components.
What principles do you find useful when writing React components?
Thanks for reading ! I hope you enjoyed and learned about the nine useful criteria of A React Component in ReactJS. Reading is one thing, but the only way to master it is to do it yourself.
Please follow and subscribe us on this blog and and support us in any way possible. Also like and share the article with others for spread valuable knowledge.
If you have any comments, questions, or think I missed something, feel free to leave them below in the comment box.
Hello Readers, CoolMonkTechie heartily welcomes you in this article.
In this article, we will talk about the ins and outs of Jest to help you get started with testing. we will learn more about the vocabulary associated with Jest testing, like mocks and spies. Also, we’ll cover some of the basics of Jest testing, like using describe blocks and the keywords it and expect. Finally, we’ll take a look at snapshot testing and why it’s particularly useful for front-end testing.
A famous quote about learning is :
” The more I live, the more I learn. The more I learn, the more I realizes, the less I know.“
So Let’s start.
What Is Jest?
Jest was created by Facebook specifically for testing React applications. It’s one of the most popular ways of testing React components. Since its introduction, the tool has gained a lot of popularity. This popularity has led to the use of Jest for testing both JavaScript front-end and back-end applications. Many large companies—including Twitter, Instagram, Pinterest, and Airbnb—use Jest for React testing.
Jest itself is actually not a library but a framework. There’s even a CLI tool that you can use from the command line. To give an example, the CLI tool allows you to run only specific tests that match a pattern. Besides that, it hosts much more functionality, which you can find in the CLI documentation.
Jest offers a test runner, assertion library, CLI tool, and great support for different mocking techniques. All of this makes it a framework and not just a library.
Jest Characteristics
From the JestJS.io website, we can find four main characteristics of Jest:
Zero config: “Jest aims to work out of the box, config free, on most JavaScript projects.” This means you can simply install Jest as a dependency for your project, and with no or minimal adjustments, you can start writing your first test.
Isolated: Isolation is a very important property when running tests. It ensures that different tests don’t influence each other’s results. For Jest, tests are executed in parallel, each running in their own process. This means they can’t interfere with other tests, and Jest acts as the orchestrator that collects the results from all the test processes.
Snapshots: Snapshots are a key feature for front-end testing because they allow you to verify the integrity of large objects. This means you don’t have to write large tests full of assertions to check if every property is present on an object and has the right type. You can simply create a snapshot and Jest will do the magic. Later, we’ll discuss in detail how snapshot testing works.
Rich API: Jest is known for having a rich API offering a lot of specific assertion types for very specific needs. Besides that, its great documentation should help you get started quickly.
Jest Vocabulary
Mock
From the Jest documentation, we can find the following description for a Jest mock:
“Mock functions make it easy to test the links between code by erasing the actual implementation of a function, capturing calls to the function (and the parameters passed in those calls).”
In addition, we can use a mock to return whatever we want it to return. This is very useful to test all the paths in our logic because we can control if a function returns a correct value, wrong value, or even throws an error.
In short, a mock can be created by assigning the following snippet of code to a function or dependency:
jest.fn()
Here’s an example of a simple mock, where we just check whether a mock has been called. We mock mockFn and call it. Thereafter, we check if the mock has been called:
A spy has a slightly different behavior but is still comparable with a mock. Again, from the official docs, we read,
“Creates a mock function similar to jest.fn() but also tracks calls to object[methodName]. Returns a Jest mock function.”
What this means is that the function acts as it normally would—however, all calls are being tracked. This allows you to verify if a function has been called the right number of times and held the right input parameters.
Below, you’ll find an example where we want to check if the play method of a video returns the correct result but also gets called with the right parameters. We spy on the play method of the video object. Next, we call the play method and check if the spy has been called and if the returned result is correct. Pretty straightforward! In the end, we must call the mockRestore method to reset a mock to its original implementation.
Let’s take a look at some basics on writing tests with Jest.
Describe Blocks
A describe block is used for organizing test cases in logical groups of tests. For example, we want to group all the tests for a specific class. We can further nest new describe blocks in an existing describe block. To continue with the example, you can add a describe block that encapsulates all the tests for a specific function of this class.
“It” or “Test“ Tests
We use the test keyword to start a new test case definition. The it keyword is an alias for the test keyword. Personally, I like to use it, which allows for more natural language flow of writing tests. For example:
Next, let’s look at the matchers Jest exposes. A matcher is used for creating assertions in combination with the expect keyword. We want to compare the output of our test with a value we expect the function to return.
Again, let’s look at a simple example where we want to check if an instance of a class is the correct class we expect. We place the test value in the expect keyword and call the exposed matcher function toBeInstanceOf(<class>) to compare the values. The test results in the following code:
it('should be instance of Car', () => {
expect(newTruck()).toBeInstanceOf(Car);
});
The complete list of exposed matchers can be found in the Jest API reference.
Snapshot Testing for React Front Ends
At last, the Jest documentation suggests using snapshot tests to detect UI changes. As I mentioned earlier, snapshot testing can also be applied for checking larger objects, or even the JSON response for API endpoints.
Let’s take a look at an example for React where we simply want to create a snapshot for a link object. The snapshot itself will be stored with the tests and should be committed alongside code changes.
If the link object changes, this test will fail in the future. If the changes to the UI elements are correct, you should update the snapshots by storing the results in the snapshot file. You can automatically update snapshots using the Jest CLI tool by adding a “-u” flag when executing the tests.
Conclusion
In this article, We understood about the Jest Framework Concepts . We learnt more about the vocabulary associated with Jest testing, like mocks and spies. Also, we have covered some of the basics of Jest testing, like using describe blocks and the keywords it and expect with snapshot testing and why it’s particularly useful for front-end testing.
Thanks for reading ! I hope you enjoyed and learned about the Jest unit testing framework concepts . Reading is one thing, but the only way to master it is to do it yourself.
Please follow and subscribe us on this blog and and support us in any way possible. Also like and share the article with others for spread valuable knowledge.
If you have any comments, questions, or think I missed something, feel free to leave them below in the comment box.
Hello Readers, CoolMonkTechie heartily welcomes you in this article.
In this article, we will learn about Recommended Design Principles used in ReactJS , and then we will also try to understand a better idea of how we decide what React does and what React doesn’t do, and what our development philosophy is like. The React recommends below common design principles which we will discuss one by one:
Composition
Common Abstraction
Escape Hatches
Stability
Interoperability
Scheduling
Developer Experience
Debugging
Configuration
Beyond the DOM
Implementation
Optimized for Tooling
Dogfooding
A famous quote about learning is :
” Learning never exhausts the mind. “
So, Let’s begin.
1. Composition
The key feature of React is composition of components. Components written by different people should work well together. It is important to us that you can add functionality to a component without causing rippling changes throughout the codebase.
For example, it should be possible to introduce some local state into a component without changing any of the components using it. Similarly, it should be possible to add some initialization and teardown code to any component when necessary.
Components are often described as “just functions” but in our view they need to be more than that to be useful. In React, components describe any composable behavior, and this includes rendering, lifecycle, and state. Some external libraries like Relay augment components with other responsibilities such as describing data dependencies. It is possible that those ideas might make it back into React too in some form.
2. Common Abstraction
In general, we resist adding features that can be implemented in userland. We don’t want to bloat your apps with useless library code. However, there are exceptions to this.
For example, if React didn’t provide support for local state or lifecycle methods, people would create custom abstractions for them. When there are multiple abstractions competing, React can’t enforce or take advantage of the properties of either of them. It has to work with the lowest common denominator.
This is why sometimes we add features to React itself. If we notice that many components implement a certain feature in incompatible or inefficient ways, we might prefer to bake it into React. We don’t do it lightly. When we do it, it’s because we are confident that raising the abstraction level benefits the whole ecosystem. State, lifecycle methods, cross-browser event normalization are good examples of this.
3. Escape Hatches
React is pragmatic. It is driven by the needs of the products written at Facebook. While it is influenced by some paradigms that are not yet fully mainstream such as functional programming, staying accessible to a wide range of developers with different skills and experience levels is an explicit goal of the project.
If we want to deprecate a pattern that we don’t like, it is our responsibility to consider all existing use cases for it and educate the community about the alternatives before we deprecate it. If some pattern that is useful for building apps is hard to express in a declarative way, we will provide an imperative API for it. If we can’t figure out a perfect API for something that we found necessary in many apps, we will provide a temporary subpar working API as long as it is possible to get rid of it later and it leaves the door open for future improvements.
4. Stability
We value API stability. At Facebook, we have more than 50 thousand components using React. Many other companies, including Twitter and Airbnb, are also heavy users of React. This is why we are usually reluctant to change public APIs or behavior.
However we think stability in the sense of “nothing changes” is overrated. It quickly turns into stagnation. Instead, we prefer the stability in the sense of “It is heavily used in production, and when something changes, there is a clear (and preferably automated) migration path.”
When we deprecate a pattern, we study its internal usage at Facebook and add deprecation warnings. They let us assess the impact of the change. Sometimes we back out if we see that it is too early, and we need to think more strategically about getting the codebases to the point where they are ready for this change.
If we are confident that the change is not too disruptive and the migration strategy is viable for all use cases, we release the deprecation warning to the open source community. We are closely in touch with many users of React outside of Facebook, and we monitor popular open source projects and guide them in fixing those deprecations.
Given the sheer size of the Facebook React codebase, successful internal migration is often a good indicator that other companies won’t have problems either. Nevertheless sometimes people point out additional use cases we haven’t thought of, and we add escape hatches for them or rethink our approach.
We don’t deprecate anything without a good reason. We recognize that sometimes deprecations warnings cause frustration but we add them because deprecations clean up the road for the improvements and new features that we and many people in the community consider valuable.
5. Interoperability
We place high value in interoperability with existing systems and gradual adoption. Facebook has a massive non-React codebase. Its website uses a mix of a server-side component system called XHP, internal UI libraries that came before React, and React itself. It is important to us that any product team can start using React for a small feature rather than rewrite their code to bet on it.
This is why React provides escape hatches to work with mutable models, and tries to work well together with other UI libraries. You can wrap an existing imperative UI into a declarative component, and vice versa. This is crucial for gradual adoption.
6. Scheduling
Even when your components are described as functions, when you use React you don’t call them directly. Every component returns a description of what needs to be rendered, and that description may include both user-written components like <LikeButton> and platform-specific components like <div>. It is up to React to “unroll” <LikeButton> at some point in the future and actually apply changes to the UI tree according to the render results of the components recursively.
This is a subtle distinction but a powerful one. Since you don’t call that component function but let React call it, it means React has the power to delay calling it if necessary. In its current implementation React walks the tree recursively and calls render functions of the whole updated tree during a single tick. However in the future it might start delaying some updates to avoid dropping frames.
This is a common theme in React design. Some popular libraries implement the “push” approach where computations are performed when the new data is available. React, however, sticks to the “pull” approach where computations can be delayed until necessary.
React is not a generic data processing library. It is a library for building user interfaces. We think that it is uniquely positioned in an app to know which computations are relevant right now and which are not.
If something is offscreen, we can delay any logic related to it. If data is arriving faster than the frame rate, we can coalesce and batch updates. We can prioritize work coming from user interactions (such as an animation caused by a button click) over less important background work (such as rendering new content just loaded from the network) to avoid dropping frames.
To be clear, we are not taking advantage of this right now. However the freedom to do something like this is why we prefer to have control over scheduling, and why setState() is asynchronous. Conceptually, we think of it as “scheduling an update”.
The control over scheduling would be harder for us to gain if we let the user directly compose views with a “push” based paradigm common in some variations of Functional Reactive Programming. We want to own the “glue” code.
It is a key goal for React that the amount of the user code that executes before yielding back into React is minimal. This ensures that React retains the capability to schedule and split work in chunks according to what it knows about the UI.
There is an internal joke in the team that React should have been called “Schedule” because React does not want to be fully “reactive”.
7. Developer Experience
Providing a good developer experience is important to us.
For example, we maintain React DevTools which let you inspect the React component tree in Chrome and Firefox. We have heard that it brings a big productivity boost both to the Facebook engineers and to the community.
We also try to go an extra mile to provide helpful developer warnings. For example, React warns you in development if you nest tags in a way that the browser doesn’t understand, or if you make a common typo in the API. Developer warnings and the related checks are the main reason why the development version of React is slower than the production version.
The usage patterns that we see internally at Facebook help us understand what the common mistakes are, and how to prevent them early. When we add new features, we try to anticipate the common mistakes and warn about them.
We are always looking out for ways to improve the developer experience. We love to hear your suggestions and accept your contributions to make it even better.
8. Debugging
When something goes wrong, it is important that you have breadcrumbs to trace the mistake to its source in the codebase. In React, props and state are those breadcrumbs.
If you see something wrong on the screen, you can open React DevTools, find the component responsible for rendering, and then see if the props and state are correct. If they are, you know that the problem is in the component’s render() function, or some function that is called by render(). The problem is isolated.
If the state is wrong, you know that the problem is caused by one of the setState() calls in this file. This, too, is relatively simple to locate and fix because usually there are only a few setState() calls in a single file.
If the props are wrong, you can traverse the tree up in the inspector, looking for the component that first “poisoned the well” by passing bad props down.
This ability to trace any UI to the data that produced it in the form of current props and state is very important to React. It is an explicit design goal that state is not “trapped” in closures and combinators, and is available to React directly.
While the UI is dynamic, we believe that synchronous render() functions of props and state turn debugging from guesswork into a boring but finite procedure. We would like to preserve this constraint in React even though it makes some use cases, like complex animations, harder.
9. Configuration
We find global runtime configuration options to be problematic.
For example, it is occasionally requested that we implement a function like React.configure(options) or React.register(component). However this poses multiple problems, and we are not aware of good solutions to them.
What if somebody calls such a function from a third-party component library? What if one React app embeds another React app, and their desired configurations are incompatible? How can a third-party component specify that it requires a particular configuration? We think that global configuration doesn’t work well with composition. Since composition is central to React, we don’t provide global configuration in code.
We do, however, provide some global configuration on the build level. For example, we provide separate development and production builds. We may also add a profiling build in the future, and we are open to considering other build flags.
10. Beyond the DOM
We see the value of React in the way it allows us to write components that have fewer bugs and compose together well. DOM is the original rendering target for React but React Native is just as important both to Facebook and the community.
Being renderer-agnostic is an important design constraint of React. It adds some overhead in the internal representations. On the other hand, any improvements to the core translate across platforms.
Having a single programming model lets us form engineering teams around products instead of platforms. So far the tradeoff has been worth it for us.
11. Implementation
We try to provide elegant APIs where possible. We are much less concerned with the implementation being elegant. The real world is far from perfect, and to a reasonable extent we prefer to put the ugly code into the library if it means the user does not have to write it. When we evaluate new code, we are looking for an implementation that is correct, performant and affords a good developer experience. Elegance is secondary.
We prefer boring code to clever code. Code is disposable and often changes. So it is important that it doesn’t introduce new internal abstractions unless absolutely necessary. Verbose code that is easy to move around, change and remove is preferred to elegant code that is prematurely abstracted and hard to change.
12. Optimized for Tooling
Some commonly used APIs have verbose names. For example, we use componentDidMount() instead of didMount() or onMount(). This is intentional. The goal is to make the points of interaction with the library highly visible.
In a massive codebase like Facebook, being able to search for uses of specific APIs is very important. We value distinct verbose names, and especially for the features that should be used sparingly. For example, dangerouslySetInnerHTML is hard to miss in a code review.
Optimizing for search is also important because of our reliance on codemods to make breaking changes. We want it to be easy and safe to apply vast automated changes across the codebase, and unique verbose names help us achieve this. Similarly, distinctive names make it easy to write custom lint rules about using React without worrying about potential false positives.
JSX plays a similar role. While it is not required with React, we use it extensively at Facebook both for aesthetic and pragmatic reasons.
In our codebase, JSX provides an unambiguous hint to the tools that they are dealing with a React element tree. This makes it possible to add build-time optimizations such as hoisting constant elements, safely lint and codemod internal component usage, and include JSX source location into the warnings.
13. Dogfooding
Dogfooding it means that our vision stays sharp and we have a focused direction going forward.
We try our best to address the problems raised by the community. However we are likely to prioritize the issues that people are also experiencing internally at Facebook. Perhaps counter-intuitively, we think this is the main reason why the community can bet on React.
Heavy internal usage gives us the confidence that React won’t disappear tomorrow. React was created at Facebook to solve its problems. It brings tangible business value to the company and is used in many of its products.
For example, we added support for web components and SVG to React even though we don’t rely on either of them internally. We are actively listening to your pain points and address them to the best of our ability. The community is what makes React special to us, and we are honored to contribute back.
After releasing many open source projects at Facebook, we have learned that trying to make everyone happy at the same time produced projects with poor focus that didn’t grow well. Instead, we found that picking a small audience and focusing on making them happy brings a positive net effect. That’s exactly what we did with React, and so far solving the problems encountered by Facebook product teams has translated well to the open source community.
The downside of this approach is that sometimes we fail to give enough focus to the things that Facebook teams don’t have to deal with, such as the “getting started” experience. We are acutely aware of this, and we are thinking of how to improve in a way that would benefit everyone in the community without making the same mistakes we did with open source projects before.
That’s all about in this article.
Conclusion
In this article, We understood about Recommended Design Principles used in ReactJS.
Thanks for reading ! I hope you enjoyed and learned about React recommended design principles. Reading is one thing, but the only way to master it is to do it yourself.
Please follow and subscribe us on this blog and and support us in any way possible. Also like and share the article with others for spread valuable knowledge.
If you have any comments, questions, or think I missed something, feel free to leave them below in the comment box.
Hello Readers, CoolMonkTechie heartily welcomes you in this article.
In this article, we will learn about topic ” Is Solid principle valid for React? “. We will focus each principle details of the SOLID one by one using below points:
What does the principle mean?
How does React adhere to it ?
SOLID is an interesting topic in React. While React doesn’t force the principles onto you, at least it often allows you to follow them.
A famous quote about learning is :
“ That is what learning is. You suddenly understand something you’ve understood all your life, but in a new way. ”
So, Let’s begin.
What does SOLID stand for?
SOLID is an acronym build by the first letter of 5 object oriented programming design principles. The basic idea is, if you follow these principles, your software gets better.
Single responsibility principle
Open/closed principle
Liskov substitution principle
Interface segregation principle
Dependency inversion principle
What do these principles imply and how does React adhere to it?
1. Single Responsibility Principle
What does it mean?
A class should only have a single responsibility.
How does React adhere to it?
React applications consist of components, which are classes that inherit from the React.Component class. You can start building your application as a component and if it gets too complex, you can split this component up into multiple smaller components.
React doesn’t force you to adhere to the principle, but you can split up your component classes into smaller components till you achieved single responsibility for all of your components.
For example, you could have a button component that just handles clicks and an input component that just handles user input. A level above you use a form component that uses multiple instances of the button and input component to get user credentials and above that a connection component that takes form data and sends it to a server.
2. Open Close Principle
What does it mean?
Software entities should be open for extension, but closed for modification. Which means you can extends it without modifying its source code.
How does React adhere to it?
Reacts component model is build around aggregation instead of inheritance. So you only extend the base React.Component and not its children. This prevents you from overriding behavior of existing components directly. The only way is to wrap it with your own component.
You could for example wrap a Button with a RedButton that always applies specific styles to the basic Button, but the Button is closed for modification.
This is less flexible than inheritance, but it also simplifies the API. While you don’t have direct access to the methods like in an extension, you only have to care about props in your aggregation.
3. Liskov Substitution Principle
What does it mean?
Objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program.
How does React adhere to it?
Well, it doesn’t use inheritance at all. Sure you extend React.Component, but this class is essentially treated as abstract in React applications, you never directly create an object from it, so you never have to replace it with a child-class later.
On the other hand, you find yourself writing aggregations that should act like their wrapped components rather often. Like the Button I mentioned before. You want that RedButton to be already styled, but you also want it to act like the Button, but since the API between components always is just props, it’s often simple to add something while your wrappers props are passed down to the wrapped component. Because everything is dynamic, your wrapper doesn’t even have to know everything about the data that would originally be passed down to the wrapped component, in the RedButton example it would just have to know about the style.
4. Interface Segregation Principle
What does it mean?
Many client-specific interfaces are better than one general-purpose interface.
How does React adhere to it?
Because React is written in JavaScript, it benefits from the dynamic nature of this language. There are no formal interfaces. If you don’t use refs, which allow you to directly call class methods of a component, the only interaction between components is via props and nobody forces you to use props you don’t need.
If you have a wrapper component that passes down an onClick handler that shows an alert with the wrapped components class name, you can use this wrapper to wrap all components that use this onClick prop and if they don’t, the handler is just ignored.
My experience with this fact was that it simplified many things, you wouldn’t get lost in defining many small interfaces beforehand. The drawback was that I often found me in situations where I passed down props the wrapped component did simply ignore silently. At least glamorous-native threw a few warnings when I tried to pass down unknown CSS attributes. For this it often helps to use PropTypes or something.
5. Dependency Inversion Principle
What does it mean?
One should depend upon abstractions, not concretions.
How does React adhere to it?
In practice, this principle is often followed by removing class names from other classes. Like, you could have a List that has Items, so you could get the idea to create your Item objects inside the List class, now you have your List tightly coupled with your Item. Somewhere in your List class is a new Item(...) or Item.create(...) etc.
React doesn’t strictly adhere to it, you can pass an array of string to your List component and create Itemchildren from it no problem.
But you can also tell the List it should simply render out its children independent of what they are, maybe add some keys to it or justify them etc.
Now you can create an array of Items, sprinkle it with some HighlightItems, both created from different string arrays and put them inside your List who won’t be the wiser.
That’s all about in this article.
Conclusion
In this article, We understood What do SOLID principles imply and how does React adhere to it. We learnt that React doesn’t force the principles onto you, but at least it often allows you to follow them. Sometimes it gets easier because of JavaScript, sometimes JavaScript makes it harder, but overall it is possible to write SOLID applications with React..
Thanks for reading ! I hope you enjoyed and learned about SOLID imply and adhere concepts in React. Reading is one thing, but the only way to master it is to do it yourself.
Please follow and subscribe us on this blog and and support us in any way possible. Also like and share the article with others for spread valuable knowledge.
If you have any comments, questions, or think I missed something, feel free to leave them below in the comment box.