score:324
How do you decide, how do you choose between these three based on the purpose/size/props/behaviour of our components?
Extending from React.PureComponent
or from React.Component
with a custom shouldComponentUpdate
method have performance implications. Using stateless functional components is an "architectural" choice and doesn't have any performance benefits out of the box (yet).
For simple, presentational-only components that need to be easily reused, prefer stateless functional components. This way you're sure they are decoupled from the actual app logic, that they are dead-easy to test and that they don't have unexpected side effects. The exception is if for some reason you have a lot of them or if you really need to optimise their render method (as you can't define
shouldComponentUpdate
for a stateless functional component).Extend
PureComponent
if you know your output depends on simple props/state ("simple" meaning no nested data structures, as PureComponent performs a shallow compare) AND you need/can get some performance improvements.Extend
Component
and implement your ownshouldComponentUpdate
if you need some performance gains by performing custom comparison logic between next/current props and state. For example, you can quickly perform a deep comparison using lodash#isEqual:class MyComponent extends Component { shouldComponentUpdate (nextProps, nextState) { return !_.isEqual(this.props, nextProps) || !_.isEqual(this.state, nextState); } }
Also, implementing your own shouldComponentUpdate
or extending from PureComponent
are optimizations, and as usual you should start looking into that only if you have performance issues (avoid premature optimizations).
As a rule of thumb, I always try to do these optimisations after the application is in a working state, with most of the features already implemented. It's a lot easier to focus on performance problems when they actually get in the way.
More details
Functional stateless components:
These are defined just using a function. Since there's no internal state for a stateless component, the output (what's rendered) only depends on the props given as input to this function.
Pros:
Simplest possible way of defining a component in React. If you don't need to manage any state, why bother with classes and inheritance? One of the main differences between a function and a class is that with the function you are sure the output depends only on the input (not on any history of the previous executions).
Ideally in your app you should aim to have as many stateless components as possible, because that normally means you moved your logic outside of the view layer and moved it to something like redux, which means you can test your real logic without having to render anything (much easier to test, more reusable, etc.).
Cons:
No lifecycle methods. You don't have a way to define
componentDidMount
and other friends. Normally you do that within a parent component higher in the hierarchy so you can turn all the children into stateless ones.No way to manually control when a re-render is needed, since you can't define
shouldComponentUpdate
. A re-render happens every time the component receives new props (no way to shallow compare, etc.). In the future, React could automatically optimise stateless components, for now there's some libraries you can use. Since stateless components are just functions, basically it's the classic problem of "function memoization".Refs are not supported: https://github.com/facebook/react/issues/4936
A component that extends PureComponent class VS A normal component that extends Component class:
React used to have a PureRenderMixin
you could attach to a class defined using React.createClass
syntax. The mixin would simply define a shouldComponentUpdate
performing a shallow comparison between the next props and the next state to check if anything there changed. If nothing changes, then there's no need to perform a re-render.
If you want to use the ES6 syntax, you can't use mixins. So for convenience React introduced a PureComponent
class you can inherit from instead of using Component
. PureComponent
just implements shouldComponentUpdate
in the same way of the PureRendererMixin
. It's mostly a convenience thing so you don't have to implement it yourself, as a shallow comparison between current/next state and props is probably the most common scenario that can give you some quick performance wins.
Example:
class UserAvatar extends Component {
render() {
return <div><img src={this.props.imageUrl} /> {{ this.props.username }} </div>
}
}
As you can see the output depends on props.imageUrl
and props.username
. If in a parent component you render <UserAvatar username="fabio" imageUrl="http://foo.com/fabio.jpg" />
with the same props, React would call render
every time, even if the output would be exactly the same. Remember though that React implements dom diffing, so the DOM would not be actually updated. Still, performing the dom diffing can be expensive, so in this scenario it would be a waste.
If the UserAvatar
component extends PureComponent
instead, a shallow compare is performed. And because props and nextProps are the same, render
will not be called at all.
Notes on the definition of "pure" in React:
In general, a "pure function" is a function that evaluates always to the same result given the same input. The output (for React, that's what is returned by the render
method) doesn't depend on any history/state and it doesn't have any side-effects (operations that change the "world" outside of the function).
In React, stateless components are not necessarily pure components according to the definition above if you call "stateless" a component that never calls this.setState
and that doesn't use this.state
.
In fact, in a PureComponent
, you can still perform side-effects during lifecycle methods. For example you could send an ajax request inside componentDidMount
or you could perform some DOM calculation to dynamically adjust the height of a div within render
.
The "Dumb components" definition has a more "practical" meaning (at least in my understanding): a dumb component "gets told" what to do by a parent component via props, and doesn't know how to do things but uses props callbacks instead.
Example of a "smart" AvatarComponent
:
class AvatarComponent extends Component {
expandAvatar () {
this.setState({ loading: true });
sendAjaxRequest(...).then(() => {
this.setState({ loading: false });
});
}
render () {
<div onClick={this.expandAvatar}>
<img src={this.props.username} />
</div>
}
}
Example of a "dumb" AvatarComponent
:
class AvatarComponent extends Component {
render () {
<div onClick={this.props.onExpandAvatar}>
{this.props.loading && <div className="spinner" />}
<img src={this.props.username} />
</div>
}
}
In the end I would say that "dumb", "stateless" and "pure" are quite different concepts that can sometimes overlap, but not necessarily, depending mostly on your use case.
score:5
React.Component
is the default "normal" component. You declare them using theclass
keyword andextends React.Component
. Think of them as a class, with lifecycles methods, event handlers and whatever methods.React.PureComponent
is aReact.Component
that implementsshouldComponentUpdate()
with a function that does a shallow comparison of itsprops
andstate
. You have to useforceUpdate()
if you know the component has props or state nested data that changed and you want to re-render. So they're not great if you need components to re-render when arrays or objects you pass as props or set in your state change.Functional components are ones that don't have lifecycle functions. They're supposedly stateless, but they're so nice and clean that we now have hooks (since React 16.8) so you can still have a state. So I guess they're just "clean components".
score:27
i am not a genius over react, but from my understanding we can use each component in following situations
Stateless component -- these are the component which doesn't have life-cycle so those components should be used in rendering repeat element of parent component such as rendering the text list which just displays the information and doesn't have any actions to perform.
Pure component -- these are the items which have life-cycle and they will always return the same result when a specific set of props is given. Those components can be used when displaying a list of results or a specific object data which doesn't have complex child elements and used to perform operations which only impact itself. such a displaying list of user cards or list of products cards( basic product info) and only action user can perform is click to view detail page or add to cart.
Normal Components or Complex Components -- I used term complex component because those are usually the page level components and consists lot of children components and since each of child can behave in its own unique way so you can't be 100% sure that it will render the same result on given state. As I said usually these should be used as container components
Source: stackoverflow.com
Related Query
- React functional stateless component, PureComponent, Component; what are the differences and when should we use what?
- What is the necessity of "export default connect" when you are connecting your react component to redux store
- What is the Flow return type of a React stateless functional component?
- What are the internal implementation differences between PureComponent and Component in React?
- In React, what is the difference between using functional component and just a function, which returns React node?
- Updating component state by Listening to socket events inside react hooks or handling them inside middleware? what are the downsides of each one?
- What's the proper way of giving react stateless functional component a typescript type
- What is the difference between React functional component <Message id> and js function formatMessage() and which one is better to use?
- What Are The Best Error Handling Processes For a Stateless React Form Both Client & Server Errors?
- How to use children with React Stateless Functional Component in TypeScript?
- What is the TypeScript return type of a React stateless component?
- What is the correct way of adding a dependency to react in your package.json for a react component
- How do react hooks determine the component that they are for?
- Accessing the State of a Functional Component with React Hooks when Testing with Enzyme
- What is the purpose of 'export' in React component declaration?
- What are context and updater arguments in the React library?
- What are the valid symbols for a React 'key'
- React - How to detect when all sub-components of a parent component are visible to the user?
- How to initialize the react functional component state from props
- Can a React portal be used in a Stateless Functional Component (SFC)?
- Class based component vs Functional components what is the difference ( Reactjs )
- What are the best practices to get React JS private methods?
- What is the second parameter for in a React functional component?
- What is the difference between React component instance property and state property?
- what is the correct type for a React instance of a component in typescript
- What is the difference between React component and React component instance?
- If the props for a child component are unchanged, does React still re-render it?
- Refactoring a React PureComponent to a hooks based functional component
- ReactJS: what is the difference between functional component and class component
- What is the correct pattern in React JS to invoke a component method on specific props change?
More Query from same tag
- concat vs push in react js
- Get multiple entries for parent object foreach child (this child is array) object within that parent
- how to output axios returned data to screen
- Comparing 2 different set of data array
- Create React App - (ESLint) Failed to load config "shared-config" to extend from. Referenced from: <PATH> in Visual Studio
- In my app,POST method is not working in axios
- --React does update the size of the containing div when it is populated by new content
- How to remove \n \t in react
- How to call a function that returns a promise from a different file
- How to 'throw' my own 'onChange' event in React?
- How to fetch data from api already in props using MDBDataTable
- I cannot use material-ui components after update to material-ui@0.15.0-beta.1
- hide imported child component on hover using styled-components
- How to toggle boolean specific states?
- Collapsible Sidebar with React and Bootstrap
- Aligning text in th tag in JSX
- how to return one index object of an array (instead of the entire array)
- React Virtualized - Screen going blank after scrolling a long list of itsm
- Using context Api with useReducer hook in next.js gives undifined back when useContext is called
- Nested list using React
- Dynamic form only shown on refresh
- Passing data onClick from child component to another child component in React.JS
- Why is the @forward naming prefix not working with variables using Sass?
- Posted comments are rendered in DOM only on refresh (React)
- react routing gives the blank screen not proper output
- should I do immutable sequence algorithm on redux container?
- Avoiding creating event handlers when using hooks
- how to add array to an object as property?, like object of more than 1 property and one of the property is array
- this.props.function name is not defined
- Working with D3.js and Immutable.js