web-dev-qa-db-fra.com

Comment utiliser React.memo avec react-redux connect?

Est-ce que quelqu'un sait comment envelopper un composant React avec React.memo quand on utilise la fonction connect de react-redux?

Par exemple, comment modifieriez-vous ce qui suit?

let Button = (props: Props) => (
  <button onClick={props.click}>{props.value}</button>
);

Button = connect(
  mapStateToProps,
  mapDispatchToProps
)(Button);

J'ai essayé:

let Button = React.memo((props: Props) => (
  <button onClick={props.click}>{props.value}</button>
));

Button = connect(
  mapStateToProps,
  mapDispatchToProps
)(Button);

Cependant, la fonction renvoyée par connect s'attend à ce qu'un composant soit transmis. Elle contient donc les erreurs suivantes:

Erreur non capturée: vous devez transmettre un composant à la fonction renvoyée par connect. Au lieu de cela reçu {"compare": null}

19
Ryc

Même problème ici. Corrigé en mettant à jour react-redux vers la version 5.1.0.

4
Maxime Chéramy

React.memo N'est rien qu'un HOC, vous pouvez donc simplement utiliser:

sans mémo:

connect(
  mapStateToProps,
  mapDispatchToProps
)(Button);

avec mémo:

connect(
  mapStateToProps,
  mapDispatchToProps
)(React.memo(Button));

Et même envelopper pour connecter: (Ceci devrait être la solution avec connect)

React.memo(
  connect(
    mapStateToProps,
    mapDispatchToProps
  )(Button)
);

Comme nous le faisons avec withRouter: withRouter(connect(...)())

4
Bhojendra Rauniyar

Votre solution devrait fonctionner (je n'ai pas essayé de copier-coller comme ça), mais vous devez également mettre à jour react-redux à la dernière version.

À propos, je pense que la bonne mise en œuvre de React.memo dans beaucoup de HOC serait d'être le plus proche du composant lui-même: l'objectif de React.memo est de vérifier si tous les nouveaux accessoires reçus par le composant sont les mêmes que les derniers accessoires. Si un élément HOC transforme ou ajoute des accessoires au composant - ce que connect effectue en mappant le magasin Redux sur les accessoires, React.memo devrait en être conscient pour pouvoir décider de mettre à jour le composant ou non.

Donc, je choisirais quelque chose comme ça:

//import what you need to import

const Component = props => <div>{/* do what you need to do here */}</div>

export default compose(
  connect(mapStateToProps, dispatchToProps),
  /* any other HOC*/
  React.memo
)(Component);
3
arnaudambro

démo de Codesandbox

Comme le message d'erreur le dit, vous devez passer un composant à la fonction renvoyée à partir de connect.
(ce qui signifie la deuxième paire de () dans connect()())

Comme React.Memo renvoie un composant, passez-le dans la deuxième fonction de connect.
Voici comment vous pouvez faire cela.

export const MemoizedDemoComponent = connect(mapStateToProps)(React.memo(DemoComponent);

Composante démo:

import React from "react";
import { connect } from "react-redux";

const DemoComponent = props => (
  <div>
    <p>My demo component fueled by: {props.fuel}!</p>
    <p>Redux: {props.state}</p>
  </div>
);

const mapStateToProps = state => ({
  state: "your redux state..."
});

// create a version that only renders on prop changes
export const MemoizedDemoComponent = connect(mapStateToProps)(
  React.memo(DemoComponent)
);

Pour un exemple de travail, vérifiez également codesandbox .

1
Roy Scheffers