2
votes

Réagir en passant un composant comme paramètre à une fonction

J'ai une fonction qui prend un composant comme paramètre. La fonction permet aux utilisateurs de rendre leurs propres popups au lieu de ceux que je fournis. Cependant, je ne suis pas en mesure d'ajouter des accessoires audit composant avant de l'ajouter à un tableau.

const addCustomSnack = (Snack, position) => {
      let id = generate();

      console.log(Snack);

      buildStyle(position);

      if (messagesNew.length >= 3) {
        que.push(Snack);
        addSnacks(messagesNew);
      } else {
        messagesNew = [...messagesNew, <Snack key={id} id={id} />];
        addSnacks(messagesNew);
      }
      console.log(messagesNew);
    };

Voici ce qui se passe

Cannot assign to read only property 'props' of object '#<Object>'

J'ai essayé le code suivant

const addCustomSnack = (Snack, position) => {
      let id = generate();

      let snackProps = {
        key: id,
        id,
      };

      Snack.props = {...Snack.props, ...snackProps}
      console.log(Snack);

      buildStyle(position);

      if (messagesNew.length >= 3) {
        que.push(Snack);
        addSnacks(messagesNew);
      } else {
        messagesNew = [...messagesNew, Snack];
        addSnacks(messagesNew);
      }
      console.log(messagesNew);
    };

Cependant, cela entraînera une erreur de type React.createElement.

Codesandbox

Est-il possible pour moi d'ajouter ces accessoires dans le composant Snack avec succès? p>


2 commentaires

Vous envoyez un composant et la mutation de ses accessoires comme Snack.props ... C'est tellement faux à bien des niveaux. À la place, composez des accessoires et ajoutez


@Rajesh Je suis désolé, j'aurais dû donner plus d'informations. Si j'utilise le Snack passé et que j'essaie d'ajouter des accessoires de cette façon, j'obtiens une erreur de type React.createElement.


4 Réponses :


0
votes

C'est exactement ce que fait une réaction High Order Component : ajouter des accessoires au composant passé en paramètre et renvoyer un composant.


1 commentaires

Oui, mais la fonction est déjà dans un composant d'ordre élevé. Veuillez consulter le lien codesandbox dans l'article pour plus de détails.



0
votes

Si vous obtenez un composant dans Snack, essayez ci-dessous la méthode

return <Snack {...snackProps} />

En utilisant le code ci-dessus, tout composant transmis à addCustomSnack


1 commentaires

L'idée est qu'il sera ajouté à un tableau de collations, mais certains accessoires doivent être ajoutés avant que je les ajoute au tableau. Veuillez consulter l'article mis à jour pour plus de détails



0
votes

Vous pouvez en quelque sorte conserver un tableau du composant à rendre, chacun avec une référence au composant et ses propriétés personnalisées, puis le rendre avec une carte, comme ceci:

// Snack list
constructor(){
  this.state = { snacks: [] }
}


// ...

const Lollipop = props => (
  <div>
    <h1>Lollipop</h1>
    <span>Taste: </span> {props.taste}
  </div>
)

const ChocolateBar = props => (
  <div>
    <h1>Chocolate bar</h1>
    <span>With fudge: </span> {props.hasFudge ? 'yes': 'no'}
  </div>
)

// Push a custom snack in the list 
const addCustomSnack = (SnackType, props) => this.state.snacks.push({SnackType, props})

// ...
addSnack(Lollipop, {taste: 'cherry'})
addSnack(Lollipop, {taste: 'cola'})
addSnack(ChocolateBar, {hasFudge: true})
addSnack(ChocolateBar, {})

// render the lsit
const SnackList = () => {
  <div>
  { this.state.snacks.map(({SnackType, props}, i) => (
    <SnackType {...props} key={i} />
  ))}
  </div>
}


0 commentaires

0
votes

React.cloneElement a fait exactement ce que je cherchais. Maintenant, l'utilisateur peut donner son propre Component, et avec cloneElement, je peux étendre les accessoires des composants et l'ajouter dans le tableau sans problème.

const addCustomSnack = (Component, position) => {
      let id = generate();


      let props = {
        removeSnack,
        key: id,
        id,
        index: id
      }

      let Snack = React.cloneElement(Component, { ...props }, null);

      buildStyle(position);


      console.log(Snack)
      if (messagesNew.length >= 3) {
        que.push(Snack);
        return addSnacks(messagesNew);
      } else {
        messagesNew = [...messagesNew, Snack];
        return addSnacks(messagesNew);
      }

    };


0 commentaires