web-dev-qa-db-fra.com

"Erreur: trop de restitutions. React limite le nombre de rendus pour empêcher une boucle infinie."

Salut, je suis coincé dans une React Function useState. Je veux juste apprendre les hooks et useState, mais je ne peux pas avoir de progrès, même trop de mal à trouver une solution. Voici ma fonction de réaction complète:

import React, { useState } from 'react';
import './MainPart.css';

function MainPart(props) {
  const [orderData_, setOrderData_] = useState(props.orderData);

  let topicData_ = props.topicData;
  let titleData_ = props.titleData;
  let infoData_ = props.infoData;

  return (
    <div className='MainPart'>
      <div className='mainWindow'>{getPics(orderData_)}</div>
      <div className='information'>
        <div className='moreNewsDivs'>
          <div className='moreNewsDiv1'>
            <h4>MORE NEWS</h4>
          </div>
          <div className='moreNewsDiv2'>
            <button
              className='previous-round'
              onClick={setOrderData_(previous(orderData_))}
            >
              &#8249;
            </button>
            &nbsp;&nbsp; &nbsp;&nbsp;
            <button href='/#' className='next-round'>
              &#8250;
            </button>
          </div>
        </div>
        <hr />
        <div className='topicDiv'>
          <h5 className='topicData'>{topicData_}</h5>
          <h5 className='titleData'>{titleData_}</h5>
          <h6 className='infoData'>{infoData_}</h6>
        </div>
      </div>
    </div>
  );
}

function previous(orderData_) {
  let newOrderData;

  if (orderData_ === 3) {
    newOrderData = 2;
    console.log(newOrderData);
    return newOrderData;
  } else if (orderData_ === 1) {
    newOrderData = 3;
    console.log(newOrderData);
    return newOrderData;
  } else {
    newOrderData = 1;
    console.log(newOrderData);
    return newOrderData;
  }
}

function next(orderData_) {
  let newOrderData;

  if (orderData_ === 3) {
    newOrderData = 1;
  } else if (orderData_ === 2) {
    newOrderData = 3;
  } else {
    newOrderData = 2;
  }
  return newOrderData;
}

const getPics = picOrder => {
  if (picOrder === 1) {
    return (
      <img
        src={require('../assets/desktopLarge/mainImage.png')}
        className='MainImage'
        alt=''
        id='mainImage'
      />
    );
  } else if (picOrder === 2) {
    return (
      <img
        src={require('../assets/desktopLarge/bridge.png')}
        className='MainImage'
        alt=''
        id='mainImage'
      />
    );
  } else {
    return (
      <img
        src={require('../assets/desktopLarge/forest.png')}
        className='MainImage'
        alt=''
        id='mainImage'
      />
    );
  }
};

export default MainPart;

Je reçois une erreur lors de l'utilisation de useState. Même en chargeant la page fraîche et sans appuyer sur quoi que ce soit, mes boutons sur l'écouteur d'événements Click ont ​​été activés et comme je l'ai mentionné précédemment au sujet de mon erreur:

"Erreur: trop de restitutions. React limite le nombre de rendus pour empêcher une boucle infinie."

2
Serkan AKMAN

Le problème peut être trouvé dans votre onClick prop:

<button className="previous-round" onClick={setOrderData_(previous(orderData_))}>&#8249;</button>

Tout entre les accolades est évalué immédiatement. Cela provoque le setOrderData_ fonction à appeler dans chaque boucle de rendu.

En enveloppant la fonction avec une fonction flèche, le code évalué se traduira par une fonction qui peut être appelée chaque fois que l'utilisateur clique sur le bouton.

Vous pouvez trouver plus d'informations sur JSX et les expressions dans les documents officiels https://reactjs.org/docs/introducing-jsx.html#embedding-expressions-in-jsx

<button className="previous-round" onClick={() => setOrderData_(previous(orderData_))}>&#8249;</button>
8
Christiaan

Quand je passe en revue votre code, j'ai trouvé quelque chose.

La fonction Onclick doit être une fonction flèche. Onclick est un événement et vous appelez juste une fonction directement dans onclick. Cela conduit à trop de rendus parce que vous définissez l'état directement dans le retour. Cela ne fonctionne pas.

Appeler setState ici fait de votre composant un concurrent pour produire des boucles infinies. le rendu doit rester pur et être utilisé pour basculer conditionnellement entre les fragments JSX/composants enfants en fonction de l'état ou des accessoires. Les rappels dans le rendu peuvent être utilisés pour mettre à jour l'état, puis effectuer un nouveau rendu en fonction du changement Cette ligne ci-dessus provient du lien ici: https://itnext.io/react-setstate-usage-and-gotchas-ac10b4e03d6

3
Anant Lalchandani

Remplacez simplement votre bouton par celui ci-dessous

<button className="previous-round" onClick={() => setOrderData_(previous(orderData_))}>&#8249;</button>

Cela se produit car la fonction onClick, si elle est utilisée sans fonctions anonymes, est appelée de manière immédiate et que setOrderData la rend à nouveau provoquant une boucle infinie. Il est donc préférable d'utiliser des fonctions anonymes.

J'espère que ça aide. n'hésitez pas à douter.

3
Gaurav Roy