【问题标题】:Too many re-renders. React limits (Next JS)太多的重新渲染。反应限制(Next JS)
【发布时间】:2021-02-23 18:01:57
【问题描述】:

下面的代码有错误 (错误:重新渲染过多。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;

【问题讨论】:

    标签: reactjs next.js


    【解决方案1】:

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

    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;
    

    【讨论】:

      【解决方案2】:

      您进入了一个无限循环,因为您在 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 分开,这使得代码更易于理解和重建。

      【讨论】:

        【解决方案3】:
        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>
              ))
              }
            </>
          );
        
        };
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-10-21
          • 2022-11-30
          • 2020-09-11
          • 2021-02-26
          • 2021-03-25
          • 2019-11-02
          • 1970-01-01
          相关资源
          最近更新 更多