I've been refactoring my app to make more components stateless/pure components; i.e., they're just functions. However, I noticed that some components will need to connect with the redux store via mapStateToProps
. Which causes me to do something like this:
const someComp = (props) => {
const {
funcFromReduxStore,
} = props;
return (
...
<SomeComponent
func={ funcFromReduxStore(myArgs) }
...
);
};
This will not work because I am executing funcFromReduxStore
. An easy solution is to wrap the prop in an arrow function. However, this causes many unnecessary re-renders b/c the function won't be bound.
The question then becomes: How do I bind a function in a stateless component?
Is it still stateless if I make it a class, without a constructor, and create a class instance field as so:
class someComp extends React.Component {
const {
funcFromReduxStore,
} = this.props,
wrapper = (x) => funcFromReduxStore(x) // equivalent way to bind w/ ES8+
render() {
...
<SomeCompnent
func={ wrapper(myArgs) }/>
...
}
}
I don't have a constructor, nor state. I want to keep the comopnent stateless, but I also want to bind the function to avoid unncessary re-renders. I also want to continue to keep it stateless b/c React has stated there will be performance benefits for stateless comopnents. Does this qualify as a workaround?
In this take, we'll look at the following React component types: Class components (formerly 'Stateful' components) Pure components. Function components (formerly 'Stateless' components)
React Programming Pattern // This is a stateless child component.
A stateless component renders output which depends upon props value, but a stateful component render depends upon the value of the state. A functional component is always a stateless component, but the class component can be stateless or stateful. There are many distinct names to stateful and stateless components.
Stateless components are simple functional component without having a local state but remember there is a hook in react to add state behavior in functional component as well. Stateful component can contains the state object and event handling function, user actions as well.
Short answer, no. Stateless functional components need to be simple functions.
You should take a look at the Recompose library for some really cool helpers that allow you to beef up your SFCs.
If you're trying to prevent unnecessary re-renders, you could look into onlyUpdateForKeys()
or pure()
.
EDIT: So, I've been thinking about this a bit more and found this really great article on React component rendering performance. One of the key points in that article that pertains to your question:
Stateless components are internally wrapped in a class without any optimizations currently applied, according to Dan Abramov.
From a tweet in July 2016
So it appears that I was wrong. "Stateless Functional Components" are classes...for now. The confusing thing is that there have been performance improvements theorized:
In the future, we’ll also be able to make performance optimizations specific to these components by avoiding unnecessary checks and memory allocations.
At this point, I think the answer to your question becomes largely subjective. When you make a class that extends a React Component, any instances of your class get the setState
prototype method. Meaning you have the ability to set state. So does that mean it's stateful even if you're not using state? Thanks to @Jordan for the link to the code. SFCs only get a render method on the prototype when they are wrapped in a class by React.
To your point about wanting to bind functions, there's only two reasons I can think of that you'd want to bind the function:
this
(the instance of the component). From your example, it doesn't seem like you need that.wrapper
function in your example seems unnecessary. The identity of the function is determined by the parent component (or mapStateToProps
, or whatever HOC).You should also take a look at React's PureComponent
which does the same kind of shallow checking that the pure()
HOC from recompose does.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With