๊ด€๋ฆฌ ๋ฉ”๋‰ด

C-log

[FE][!ERRO]Too many re-renders. React limits the number of renders to prevent an infinite loop. ๋ณธ๋ฌธ

๐Ÿ’ป๊ฐœ๋ฐœ ๋…ธํŠธ/๋‚˜๋งŒ์˜ ์‹œํ—˜์ง€

[FE][!ERRO]Too many re-renders. React limits the number of renders to prevent an infinite loop.

4:Bee 2024. 3. 13. 22:51
728x90

 

json-server api๋ฅผ ๋‹ด๋‹นํ•˜๊ณ  ์žˆ๋˜ useEffect๋ฅผ ์ปค์Šคํ…€ ํ›…์œผ๋กœ ๋งŒ๋“ค์–ด ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด์„œ ๋ถ„๋ฆฌํ•˜๋˜ ๋„์ค‘์— ๋ฐœ์ƒํ•œ ์—๋Ÿฌ์ด๋‹ค. Too many re-render ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ์ด์œ ๋Š” ๋Œ€ํ‘œ์ ์œผ๋ก  uesEffect์— ์˜์กด์„ฑ ๋ฐฐ์—ด์„ ์‚ฝ์ž…ํ•˜์ง€ ์•Š์•˜์„ ๊ฒฝ์šฐ์— ๋ฐœ์ƒํ•œ๋‹ค. ํ•˜์ง€๋งŒ ๋‚˜์˜ ๊ฒฝ์šฐ ์ปค์Šคํ…€ ํ›…์—๋Š” useEffect์˜ ์˜์กด์„ฑ ๋ฐฐ์—ด์ด ๋ฌธ์ œ ์—†์ด ์ž˜ ์‚ฝ์ž… ๋˜์–ด ์žˆ๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด ํ˜„์žฌ ์ปค์Šคํ…€ ํ›…์˜ ๋ฌธ์ œ๊ฐ€ ์•„๋‹ˆ๋ผ ์ปค์Šคํ…€ ํ›…์„ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์ปดํฌ๋„ŒํŠธ(LabExam)์— ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค๊ณ  ํŒ๋‹จํ–ˆ๋‹ค. ์•„๋ž˜ ์ฝ”๋“œ๋Š” ๋‚˜์˜ ์ปค์Šคํ…€ ํ›…์ด๋‹ค.

* useLabExamAxios.js

 
import { useState, useEffect } from "react";
import axios from 'axios';

export default function useLabExamAxios(limit) {

  const [data, setData] = useState([]);

  useEffect(() => {
    axios.get('http://localhost:3001/sample')
      .then(res => {
        setData(res.data.slice(0, limit));
      })
      .catch((error) => {
        console.error("Error fetching data:", error);
      });
  }, [limit]);

  return data;
}
 

## ์ปค์Šคํ…€ ํ›…์ด๋ž€?

๋”๋ณด๊ธฐ

### ํ›…์ธ๋ž€?

### ์ปค์Šคํ…€ ํ›…์ด๋ž€?

ํ˜„์žฌ useLabExamAxios๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์ปดํฌ๋„ŒํŠธ์—์„œ useState๊ฐ€ useLabExamAxios์™€ ๋™์ผํ•˜๊ฒŒ ๋‘๋ฒˆ ์š”์ฒญ์ด ๋˜๊ณ  ์žˆ๋‹ค. ์•„๋ž˜ ์ฝ”๋“œ๋Š” useLabExamAxios๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์ปดํฌ๋„ŒํŠธ์˜ ์ฝ”๋“œ์ด๋‹ค.

 
import React, { useState } from "react";
import { Link } from "react-router-dom";
import "../css/style.css"

import useLabExamAxios from "../function/useLabExamAxios";
import useAxios from "../function/useAxios";
import shuffleArray from '../function/shuffleArray'
import { renderImages, parseImages } from '../function/renderImages'

export default function LabExam() {
  const [data, setData] = useState([]);
  const [limit, setLimit] = useState(5);
  const [isCommentary, setIsCommentary] = useState(false); //๋‹ต์•ˆ์ง€ ์ƒํƒœ๊ด€๋ฆฌ

  const testData = useLabExamAxios(limit)
  setData(testData);
  ...
 

์ด๋Š” ์ฆ‰, ์™ธ๋ถ€์—๋„ ๋‚ด๋ถ€์—๋„ useState๊ฐ€ ์—ฌ๋Ÿฌ๋ฒˆ ๋ Œ๋”๋ง์ด ๋˜๊ณ  ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค. ์ด๋Š” ๋ฌดํ•œ ๋ Œ๋”๋ง์„ ๋ฐœ์ƒ ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ ์™ธ๋ถ€, ๋‚ด๋ถ€์— useState๊ฐ€ ํ•˜๋‚˜๋งŒ ์กด์žฌ ํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ๋˜๋Š” ์™ธ๋ถ€์— ์žˆ๋Š” useState๋ฅผ ํ•œ๋ฒˆ ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์žˆ๊ฒŒ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด์•ผํ•œ๋‹ค. ๋ณ€๊ฒฝ๋œ ์ฝ”๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

 
 ...
import useLabExamAxios from "../function/useLabExamAxios";
import shuffleArray from '../function/shuffleArray'
import { renderImages, parseImages } from '../function/renderImages'

export default function LabExam() {
  const [data, setData] = useState([]);
  const [limit, setLimit] = useState(5);
  const [isCommentary, setIsCommentary] = useState(false); //๋‹ต์•ˆ์ง€ ์ƒํƒœ๊ด€๋ฆฌ

  const testData = useLabExamAxios(limit);

  useEffect(() => {
    setData(testData);
  }, [testData]);
  ...
 

์ด๋ ‡๊ฒŒ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ฒŒ ๋œ๋‹ค๋ฉด ๊ณผ์—ฐ ์ปค์Šคํ…€ํ›…์ด ๋งž๋Š” ๊ฒƒ์ผ๊นŒ? ๋”ฐ๋กœ ํ•จ์ˆ˜๋กœ ๋งŒ๋“ค์–ด๋‚ด๋Š” ๋ชฉ์ ์€ ๊ฐ€๋…์„ฑ์„ ๋†’์ด๊ธฐ ์œ„ํ•จ์ธ๋ฐ ์ด๋ ‡๊ฒŒ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ฒŒ ๋œ๋‹ค๋ฉด ์™ธ๋ถ€์™€ ๋‚ด๋ถ€์—์„œ ์ด์ค‘์ ์œผ๋กœ useEffect๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๊ธฐ์— ๊ฐ€๋…์„ฑ์ด ๋–จ์–ด์ง„๋‹ค. ๋”ฐ๋ผ์„œ ์ปค์Šคํ…€ ํ›…์„ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•๋ณด๋‹ค๋Š” ์™ธ๋ถ€์— useEffect๋ฅผ ์œ ์ง€ํ•œ ์ƒํƒœ๋กœ ๋‚ด๋ถ€์— ์žˆ๋Š” Axios๋งŒ ๋”ฐ๋กœ ํ•จ์ˆ˜๋กœ ๋ถ„๋ฆฌํ•˜๊ณ  ์™ธ๋ถ€์— useEffect๋ฅผ ์œ ์ง€ํ•˜๋Š” ํŽธ์ด ๊ฐ€๋…์„ฑ์„ ๋†’์ธ๋‹ค๊ณ  ํŒ๋‹จ์ด ๋œ๋‹ค. ์ด์— ๋”ฐ๋ผ ๋” ์ด์ƒ ์ปค์Šคํ…€ ํ›…์ด ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ํŒŒ์ผ ๋ช…๋„ use๋ฅผ ์ œ์™ธํ•ด์„œ ๋‹ค์‹œ ์ˆ˜์ • ํ–ˆ๋‹ค. ์ˆ˜์ •๋œ ์ฝ”๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

* labExamAxios.js

 
import axios from 'axios';

export default function labExamAxios(limit, setData) {
  axios.get('http://localhost:3001/sample')
    .then(res => {
      setData(res.data.slice(0, limit));
    })
    .catch((error) => {
      console.error("Error fetching data:", error);
    });
}
 

์™ธ๋ถ€ ์ปดํฌ๋„ŒํŠธ์— useEffect๋ฅผ ์œ ์ง€ํ•˜๊ณ  ๋‚ด๋ถ€ ์ปดํฌ๋„ŒํŠธ์—๋Š” axios๋งŒ ๋ถ„๋ฆฌํ•œ ๋ชจ์Šต์ด๋‹ค. ์™ธ๋ถ€ ์ปดํฌ๋„ŒํŠธ๋Š” import๋ฅผ ํ•ด์˜ค๊ณ  ์•„๋ž˜์™€ ๊ฐ™์ด ๊ตฌ์„ฑํ–ˆ๋‹ค.

 
  useEffect(() => {
    labExamAxios(limit, setData)
  }, [limit]);
 

# suffleArray ํ•จ์ˆ˜ / handleShuffle ํ•จ์ˆ˜ ๋ถ„๋ฆฌ ์ค‘ ๋ฐœ์ƒํ•œ Too many re-render ์—๋Ÿฌ

axios์— ์ด์–ด suffleArray๋ฅผ ๋ถ„๋ฆฌํ•˜๋Š” ๋„์ค‘์—๋„ ๋ฐœ์ƒ์ด ๋˜์—ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ƒ๊ฐ๋ณด๋‹ค ๊ฐ„๋‹จํ•œ ์ด์œ ์˜€๋‹ค. ์šฐ์„  ๋ถ„๋ฆฌ๋œ ํ•จ์ˆ˜๋“ค์€ ์•„๋ž˜์™€๊ฐ™๋‹ค. 

* shuffleArray.js

 
// shuffleArray(Fisher-Yates) ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐฐ์—ด์„ ์„ž๋Š” ํ•จ์ˆ˜
export function shuffleArray(arrayItem) {
  for (let i = arrayItem.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [arrayItem[i], arrayItem[j]] = [arrayItem[j], arrayItem[i]];
  }
  return arrayItem;
}
// ๋ฌธ์ œ๋ฅผ ์„ž๋Š” ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋ฒ„ํŠผ ํด๋ฆญ ํ•ธ๋“ค๋Ÿฌ
export function handleShuffle(data, setData) {
  const shuffledData = shuffleArray(data);
  setData([...shuffledData]); // ์ƒˆ๋กœ์šด ๋ฐฐ์—ด๋กœ ์„ค์ •ํ•˜์—ฌ React๊ฐ€ ์—…๋ฐ์ดํŠธ๋ฅผ ๊ฐ์ง€ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•จ
  return shuffledData;
};
 

์ด์— ์ ์šฉ๋œ ์™ธ๋ถ€ ์ปดํฌ๋„ŒํŠธ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

 
  ...
<button onClick={handleShuffle(data, setData)}>Shuffle</button>
  ...
 

์—ฌ๊ธฐ์—์„œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒ๋œ ๊ฒƒ์ด๋‹ค. ์›๋ž˜ onClick๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด ํ•จ์ˆ˜์˜ ๊ด„ํ˜ธ'()'๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ํ•จ์ˆ˜ ๋ช…๋งŒ ์ž‘์„ฑํ•ด์•ผํ•œ๋‹ค. ํ•˜์ง€๋งŒ handleShuffleํ•จ์ˆ˜๊ฐ€ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๊ฐ€์ง€๊ฒŒ ๋˜๋ฉด์„œ ๋ฌดํ•œ์œผ๋กœ ํด๋ฆญ๋˜๊ณ  ์žˆ๋Š” ๊ฒƒ์ด์˜€๋‹ค. ๋”ฐ๋ผ์„œ ๋‹ค์‹œ ํ•œ๋ฒˆ ํ™”์‚ดํ‘œ๊ธฐ ํ•จ์ˆ˜๋กœ ๊ฐ์‹ธ์ค˜์•ผ ํ•œ๋‹ค. ์ˆ˜์ •๋œ ์ฝ”๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

 
  ...
<button onClick={() => handleShuffle(data, setData)}>Shuffle</button>
  ...
 

์ด๋ ‡๊ฒŒ ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•ด์ฃผ๋ฉด ๋ชจ๋“  ๋ฌดํ•œ ๋ Œ๋” ์—๋Ÿฌ๋Š” ์‚ฌ๋ผ์ง€๊ฒŒ๋˜๊ณ  ์•ˆ์ „ํ•˜๊ฒŒ ์ฝ”๋“œ๋ฅผ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๋‹ค.

728x90
Comments