Languages
[Edit]
EN

React - memo on event props

7 points
Created by:
DEX7RA
580

In this article, we would like to show how to create memo on props that uses event methods in React component.

The solution presented in the article shows how in an easy way, we can prevent components' unnecessary re-rendering cycles when we pass methods in props to components. In the solution, it is enough to add $ prefix before prop name to memorize component for that method.

In practice, that solution can be used to memorize event props.

The example shows 2 buttons:

  • the first one is re-rendered by changed onClick method,
  • the second one is not re-rendered with changed $onClick method.

Note: by "changed onClick method" we understand: each time new arrow function is created that forces child component re-rendering.

Practical example:

// ONLINE-RUNNER:browser;

// Note: Uncomment import lines while working with your project.
// import React from 'react';
// import ReactDOM from 'react-dom';

const wrapProps = (state, props) => {
    const wrapper = {};
    const keys = Object.keys(props);
    for (const key of keys) {
        const value = props[key];
        if (key[0] === '$') {
            if (typeof value === 'function') {
                let name = key.slice(1);
                let pipe = state[name];
                if (pipe) {
                    pipe.method = value;
                } else {
                    pipe = state[name] = {
                        method: value,
                        proxy: (...args) => pipe.method?.(...args)
                    };
                }
                wrapper[name] = pipe.proxy;
            } else {
                throw new Error('Incorrect function property name prefix usage.');
            }
        } else {
            wrapper[key] = value;
        }
    }
    return wrapper;
};

const useWrapper = (props) => {
    const [state] = React.useState({});
    return wrapProps(state, props);
};

const pipe = (component) => {
    const WrapperA = React.memo(component);
    const WrapperB = (props) => {
        const wrapper = useWrapper(props);
        return React.createElement(WrapperA, wrapper);
    };
    WrapperB.displayName = `Pipe(${component.displayName || component.name})`;
    return WrapperB;
};


// Usage example:

const Button = ({text, onClick}) => {
    console.log(`Button rendering (${text}).`);
    return (
        <button onClick={onClick}>{text}</button>
    );
};

const PipedButton = pipe(Button);

const App = () => {
    const [counter, setCounter] = React.useState(0);
    return (
        <div>
          <div>Value: {counter}</div>
          <PipedButton text="with  onClick event"  onClick={() => setCounter(value => value + 1)} />
          <PipedButton text="with $onClick event" $onClick={() => setCounter(value => value + 1)} />
        </div>
    );
};

const root = document.querySelector('#root');
ReactDOM.render(<App />, root);

Summary: $onClick prop uses memo on function, preventing component against unnecessary re-rendering.

Hint: the truth is: $ added to prop, creates proxy method that is never changed later, preventing component against unnecessary re-rendering.

 

Alternative titles

  1. React - memo only on method props
Donate to Dirask
Our content is created by volunteers - like Wikipedia. If you think, the things we do are good, donate us. Thanks!
Join to our subscribers to be up to date with content, news and offers.
Native Advertising
🚀
Get your tech brand or product in front of software developers.
For more information Contact us
Dirask - we help you to
solve coding problems.
Ask question.

❤️💻 🙂

Join