Recompose is used to create react libraries for functional and higher-order components

Recompose project address

Recompose is the Lodash of the React stack. It provides many utility functions for creating React functional components and higher-order components, including compose, Branch, withState, withStateHandlers, and so on

Basic usage

withState

Const enhance = withState('counter', 'setCounter', 0); const enhance = withState('counter', 'setCounter', 0); const Counter = enhance(({ counter, setCounter }) => <div> Count: {counter} <button onClick={() => setCounter(n => n + 1)}>Increment</button> <button onClick={() => setCounter(n => n - 1)}>Decrement</button> </div> )Copy the code

Implement shouldComponentUpdate for functional components using Pure and onlyUpdateForKeys

// Stateless component const ExpensiveComponent = ({propA, PropB}) => <div>{/* XXX */}</div> // Use pure (effect is the same as extends PureComponent) const OptimizedComponent = Pure (ExpensiveComponent) // Specifies props update const HyperOptimizedComponent = onlyUpdateForKeys(['propA', 'propB'])(ExpensiveComponent)Copy the code

Advanced usage

Compose combination

The compose method is the same as the compose method in the redux source code. Because the React higher-order component actually takes a component as an argument and returns a higher-order function for that component, you can use the compose function to compose different higher-order components directly for the same component

func0 = (component) => finalComponent;
func1 = (component) => finalComponent;
func2 = (component) => finalComponent;

func0(func1(func2(Component)));Copy the code

Looking directly at the source code implementation of Recompose, you’ll see that many methods such as withState, withProps, withHandles, and withContext return a higher-order component directly. They all look like this

const withXXX = (... Args) => (BaseComponent) => {class WithXXX extends PureComponent {// internal implementation} return WithXXX; }Copy the code

For these higher-order components, you can compose them using the compose method. There is no limit to the number of parameters in the compose function, but the component must be a higher-order component that can input a component and return a new component. In this way, the side effects of the component can be stripped away so that external business logic does not interfere with the component itself

// Toggle.js const Toggle = ({ title, message, toggleVisibility, isVisible, name }) => ( <div> <h1>{title}</h1> {isVisible ? <p>{"I'm visible"}</p> : <p>{'Not Visible'}</p>} <p>{message}</p> <p>{name}</p> <button onClick={toggleVisibility}> Click me! </button> </div> ); Toggle export default compose(withState('isVisible', 'toggleVis', false), withHandlers({ toggleVisibility: ({ toggleVis, isVisible }) => (event) => toggleVis(! isVisible), }), withProps(({ isVisible }) => ({ title: isVisible ? 'This is the visible title' : 'This is the default title', message: isVisible ? 'Hello I am Visible' : 'I am not visible yet, click the button! ', })), )(Toggle);Copy the code

Life cycle function

Recompose favors functional stateless components because they can be written easily and can strip out useless logic. Lifecycle functions can be added to stateless components using lifecycle functions

import { lifecycle } from 'recompose';

const cycle = {
  componentDidMount() {
    // didMount
  },
  componentWillReceiveProps(nextProps) {
    // nextProps
  },
  componentWillUnmount() {
    // willUnmount
  }
};

const Toggle = (props) => <div>{props.value}</div>;

export default lifecycle(cycle)(Toggle);Copy the code

Nest component hierarchy nesting

The NEST function is used to nest the incoming components sequentially, layer by layer, to form such a JSX structure

<A>
  <B>
    <C>
      {/*xxx*/}
    </C>
  </B>
</A>Copy the code

Using Nest, you can nest these components together automatically

import { nest } from 'recompose';

const A = ({data, children}) => (
  <div>
    this is some node
    {children}
  </div>
);
const B = ({data, children}) => (
  <div>
    this is some node
    {children}
  </div>
);
const C = ({data, children}) => (
  <div>
    this is some node
    {children}
  </div>
);
export default nest(A, B, C);Copy the code

Note that the order in which components are passed determines the nesting level, and that the parent component needs to reference the child component with {children}