重新渲染过多。反应限制(下一个JS)

时间:2020-11-11 18:16:02

标签: reactjs next.js

我的以下代码有误 (错误:重新渲染过多。React限制了渲染数量,以防止无限循环。)

目标是在除最后一项之外的每个项目上添加一个跨度。

最好的方法是什么?

const Section = () => {

  const [lastItem, setlastItem] = React.useState(false);

  // rendu des Sections
  const sectionLentgh = Data.sections.length;
  const sectionList = Data.sections.map((item, i) => {
    
    // AJout du séparateur
    if (sectionLentgh === i + 1) {
      setlastItem(false);
    } else {
      setlastItem(true);
    }

    console.log(i);

    return (
      <div>
        <h2>{item.title}</h2>
        <img src={`/images/${item.image}`}></img>
        <span style={{ backgroundImage:`url(/images/${item.image})` }}></span>
        <p dangerouslySetInnerHTML={{ __html: item.description }} />
        <span className={`${ lastItem ? styles.separator : '' }`}></span>
      </div>
    );
  })

  return (
    <>
    <div className={styles.sections}>
        {sectionList}
    </div>
    </>
  );

};

export default Section;

3 个答案:

答案 0 :(得分:0)

只需使用数组的长度并将其与迭代索引进行比较:

const Section = () => {
  const sectionLength = Data.sections.length;
  const sectionList = Data.sections.map((item, i) => {
    const lastItem = i === (sectionLength - 1);
    return (
      <div>
        <h2>{item.title}</h2>
        <img src={`/images/${item.image}`}></img>
        <span style={{ backgroundImage: `url(/images/${item.image})` }}></span>
        <p dangerouslySetInnerHTML={{ __html: item.description }} />
        <span className={`${lastItem ? styles.separator : ""}`}></span>
      </div>
    );
  });

  return (
    <>
      <div className={styles.sections}>{sectionList}</div>
    </>
  );
};

export default Section;

答案 1 :(得分:0)

您进入无限循环,因为您在map函数中调用了setlastItem,这反过来在每个渲染器上重新运行。由于setState触发新的渲染,因此会导致无限循环。

您想要的是将sectionList的生成放入useEffect中,该效果仅在Data.sections每次更改时才重新运行。 像这样:

const Section = () => {
  const [sectionList, setSectionList] = useState([]);
  useEffect(() => {
    if(!Data.sections|| Data.sections.length < 2){
      setSectionList([]);
    } else {
     setSectionList(Data.sections.splice(-1, 1));
    }

  }, [Data.sections]);
    
  return (
      <div className={styles.sections}>
        {sectionList.map(item => (
           <div>
             <h2>{item.title}</h2>
             <img src={`/images/${item.image}`}></img>
             <span style={{ backgroundImage: `url(/images/${item.image})`}
               }></span>
             <p dangerouslySetInnerHTML={{ __html: item.description }} />
             <span className={`${lastItem ? styles.separator : ""}`}></span>
           </div>
        )}
      </div>
  );
};

如您所见,我发现从jsx中分离了数据的生成,这使代码更易于理解和重建。

答案 2 :(得分:0)

const Section = () => {

  return (
    <>
      <div className={styles.sections}>
        {Data.sections.map((item, id) => (
          <div key={id}>
            <h2>{item.title}</h2>
            <img src={`/images/${item.image}`}></img>
            <span style={{ backgroundImage: `url(/images/${item.image})` }
            }></span>
            <p dangerouslySetInnerHTML={{ __html: item.description }} />
            <span className={`${id < (Data.sections.length - 1) ? styles.separator : ""}`}></span>
          </div>
        ))
        }
      </div>
    </>
  );
  
};

const Section = () => {

  return (
    <>
      {Data.sections.map((item, id) => (
        <div key={id}>
          <div className={styles.sections} key={id}>
            <h2>{item.title}</h2>
            <img src={`/images/${item.image}`}></img>
            <span style={{ backgroundImage: `url(/images/${item.image})` }
            }></span>
            <p dangerouslySetInnerHTML={{ __html: item.description }} />

          </div>
          { id < (Data.sections.length - 1) &&
            <span className={styles.separator}></span>
          }
        </div>
      ))
      }
    </>
  );

};