This primer will try to explain what recompose is by writing a non-recompose React component and then progressively refactoring it until you end up using withState
from recompose.
import React, { Component} from 'react';
class MyComponent extends Component {
state = {
isShowingStuff: false,
}
setIsShowingStuff = (isShowing) => this.setState({ isShowingStuff: isShowing})
render() {
const { isShowingStuff } = this.state;
return (
<div>
<button onClick={() => this.setIsShowingStuff(!isShowingStuff)}> Click me </button>
<span> Some stuff </span>
{isShowingStuff && <span> More stuff </span>}
<span> Even some more stuff </span>
<div>
)
}
}
This is fine. Lets refactor it to follow the common best practice of smart and dumb components.
import React, { Component} from 'react';
const MyDumbComponent = ({ isShowingStuff, setIsShowingStuff }) => (
<div>
<button onClick={() => setIsShowingStuff(!isShowingStuff)}> Click me </button>
<span> Some stuff </span>
{isShowingStuff && <span> More stuff </span>}
<span> Even some more stuff </span>
<div>
)
class MySmartComponent extends Component {
state = {
isShowingStuff: false,
}
setIsShowingStuff = (isShowing) => this.setState({ isShowingStuff: isShowing})
render() {
const { isShowingStuff } = this.state;
return <MyDumbComponent isShowingStuff={isShowingStuff} setIsShowingStuff={this.setIsShowingStuff}/>
}
}
Ok, but what if we want to share the logic contained in MySmartComponent
with other dumb components? You write a Higher Order Component.
import React, { Component} from 'react';
const MyDumbComponent = ({ isShowingStuff, setIsShowingStuff }) => (
<div>
<button onClick={() => setIsShowingStuff(!isShowingStuff)}> Click me </button>
<span> Some stuff </span>
{isShowingStuff && <span> More stuff </span>}
<span> Even some more stuff </span>
<div>
)
// A HOC is a function that returns a component definition.
const withIsShowingStuff = (ComponentType) => class SmartComponent extends Component {
state = {
isShowingStuff: false,
}
setIsShowingStuff = (isShowing) => this.setState({ isShowingStuff: isShowing})
render() {
const { isShowingStuff } = this.state;
return <ComponentType isShowingStuff={isShowingStuff} setIsShowingStuff={this.setIsShowingStuff}/>
}
}
// Cool now we can apply it
const MySmartComponent = withIsShowingStuff(MyDumbComponent);
That is cool, but recompose takes it a step further and provides a toolbelt to create HOCs. With recompose you can do the above in fewer lines of code.
import React, { Component} from 'react';
import { withState } from 'recompose';
const MyDumbComponent = ({ isShowingStuff, setIsShowingStuff }) => (
<div>
<button onClick={() => setIsShowingStuff(!isShowingStuff)}> Click me </button>
<span> Some stuff </span>
{isShowingStuff && <span> More stuff </span>}
<span> Even some more stuff </span>
<div>
)
const withIsShowingStuff = withState('isShowingStuff', 'setIsShowingStuff', false);
const MySmartComponent = withIsShowingStuff(MyDumbComponent);
Recompose provides more utils than withState
but these examples capture the gist of it.