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

C-log

์ˆ˜์ •๋œ API๋กœ ๊ธฐ์กด ํ•จ์ˆ˜ ์ˆ˜์ • ๋ณธ๋ฌธ

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

์ˆ˜์ •๋œ API๋กœ ๊ธฐ์กด ํ•จ์ˆ˜ ์ˆ˜์ •

4:Bee 2024. 3. 9. 01:37
728x90

์ตœ๊ทผ ์žฆ์€ ํšŒ์˜์™€ ๋ณ€๋™๋˜๋Š” api์˜ ์ฝ”๋“œ๋“ค์ด ๋งŽ์•„ ์ž์ฃผ push ํ•˜์ง€ ๋ชปํ–ˆ๋‹ค. commit๋งŒ ๋“ค์–ด ๋‚ฌ๊ณ  ๊นƒํ—ˆ๋ธŒ ์ž”๋””๋Š” ํ……ํ……๋น„์–ด ์žˆ์–ด์„œ ์•„์‰ฌ์›€์ด ์กฐ๊ธˆ์€ ๋งŽ์ด ๋‚จ๋Š”๋‹ค.

api์˜ ํ˜•ํƒœ๊ฐ€ ๋ฐ”๋€Œ์—ˆ๋‹ค. ๊ธฐ์กด์˜ ํ•จ์ˆ˜์—์„œ ์ด๋ฏธ์ง€๋ฅผ ํŒŒ์‹ฑํ•˜์ง€ ๋ชปํ•˜๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์˜€๋‹ค. ๊ทธ ์ด์œ ๋Š” api์˜ ๊ตฌ์กฐ๊ฐ€ ๋ฐ”๋€Œ์—ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์šฐ์„  ๊ธฐ์กด ํ•จ์ˆ˜์™€ ๋ณ€๊ฒฝ๋œ ํ•จ์ˆ˜์˜ ์ฐจ์ด๋ฅผ ์‚ดํŽด๋ณด๋ฉด ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

๊ธฐ์กด outside image๋ฅผ ๋ Œ๋”๋งํ•˜๋Š” ํ•จ์ˆ˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค. ๋‹จ์ˆœํžˆ ์ด๋ฏธ์ง€์˜ image๊ฐ€ ๋ฐฐ์—ด์ผ ๋•Œ ํ•ด๋‹น api๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๋ฐฉ์‹์ด๋‹ค. (์•„๋ž˜ ๋”๋ณด๊ธฐ๋กœ ์ด์ „ api์˜ ํ˜•ํƒœ๋ฅผ ํ™•์ธํ•ด ๋ณด๋ฉด์„œ ๋น„๊ตํ•˜๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™๋‹ค.)

๋”๋ณด๊ธฐ
 
 "images": [
    "https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistoryFblog..png",
    "https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2mg.png"
 ]

// ์ด๋ฏธ์ง€ ๋ Œ๋”๋ง ํ•จ์ˆ˜
const renderImages = (outsideImage) => {
  if (Array.isArray(outsideImage) && outsideImage.length > 0) {
    return outsideImage.map((image, imageIndex) => (
      <img
        key={imageIndex}
        src={image}
        alt={`Image ${imageIndex + 1}`}
        style={{ width: '100%' }}
     />
    ));
  } else {
    return null;
  }
};
 

์ฆ‰, ํ˜„์žฌ๋Š” image ์•ˆ์— url์™€ attribute ๊ทธ๋ฆฌ๊ณ  class ์ด๋ฆ„์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. ์ ‘๊ทผ ๋ฐฉ๋ฒ•์€ ๋‹จ์ˆœํžˆ image๊ฐ€ ์•„๋‹Œ image.url๊ณผ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์ ‘๊ทผ์„ ํ•˜๋ฉด ๋˜๋Š” ๊ฒƒ์ด๋‹ค.  ์•„๋ž˜ ์ฝ”๋“œ๋Š” ๋ณ€๊ฒฝ๋œ ๋ถ€๋ถ„์ด๋‹ค. ์ฐธ๊ณ ๋กœ image์˜ alt ๋˜ํ•œ 1๋ถ€ํ„ฐ ์‹œ์ž‘์ด ์•„๋‹Œ 0๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜๊ธฐ๋กœ ์•ฝ์† ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— 1์„ ๋”ํ•˜์ง€ ์•Š๋Š”๋‹ค.

 
  // ์ด๋ฏธ์ง€ ๋ Œ๋”๋ง ํ•จ์ˆ˜ ์ˆ˜์ • / ํ˜„์žฌ ๋ณ€์ˆ˜๋ช…์€ imageData๋กœ ๋ณ€๊ฒฝํ•˜์˜€๋‹ค.
  const renderImages = ( outsideImage ) => {
    if (Array.isArray( outsideImage ) && outsideImage .length > 0) {
      return outsideImage .map((image, imageIndex) => (
        <img
          key={imageIndex}
          src={image.url} // ์ด๋ฏธ์ง€ ๊ฐ์ฒด์—์„œ URL์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
          alt={`Image ${imageIndex}`}
          style={{ width: '100%' }}
        />
      ));
    } else {
      return null;
    }
  };

๋ณ€๊ฒฝ๋œ api๋ฅผ ๋ณด๋ฉด ์ด๋ฏธ์ง€ ๊ฐ์ฒด๋กœ ์ ‘๊ทผํ•ด์„œ url์„ ๊ฐ€์ง€๊ณ  ์™€์•ผํ•œ๋‹ค. ๊ทธ๋ž˜์„œ image.url๋กœ ์ ‘๊ทผํ•ด์„œ ๋ณ€๊ฒฝํ•˜๋ฉด ๋œ๋‹ค.  (์•„๋ž˜ ๋”๋ณด๊ธฐ๋กœ ๋ณ€๊ฒฝ๋œ api์˜ ํ˜•ํƒœ๋ฅผ ํ™•์ธํ•ด ๋ณด๋ฉด์„œ ๋น„๊ตํ•˜๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™๋‹ค.)

๋”๋ณด๊ธฐ
 
 "question_images_out": [
                {
                    "url": "https://img1.daumcdn.net/thumb/R1280x0/?Rk%2Fimg.png",
                    "description": "",
                    "attribute": ""
                }
            ],

๋‹ค์Œ์œผ๋กœ ์ˆ˜์ •๋˜๋Š” ํ•จ์ˆ˜๋Š” inside image๋ฅผ ํŒŒ์‹ฑํ•˜๊ณ  ๋ Œ๋”๋งํ•˜๋Š” ํ•จ์ˆ˜์ด๋‹ค. ์—ญ์‹œ๋‚˜ ์œ„์˜ ํ•จ์ˆ˜์™€ ๊ฐ™์ด api์˜ ์ด๋ฏธ์ง€ ๊ฐ์ฒด์— ์ ‘๊ทผํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด์•ผ ํ•œ๋‹ค.

 
  const parseImageTag = (question, questionImgUrls) => {
    let parsedQuestion = question;

    // ์ด๋ฏธ์ง€ URL ๋ฐฐ์—ด์ด ์ •์˜๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
    if (Array.isArray(questionImgUrls) && questionImgUrls.length > 0) {
      // ์ด๋ฏธ์ง€ URL ๋ฐฐ์—ด์˜ ๊ฐ ์š”์†Œ๋ฅผ ๋ฐ˜๋ณตํ•˜์—ฌ ์ด๋ฏธ์ง€ ํƒœ๊ทธ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์งˆ๋ฌธ์— ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค.
      questionImgUrls.forEach((imageUrl, index) => {
        // ์ •๊ทœ ํ‘œํ˜„์‹์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฏธ์ง€ ํƒœ๊ทธ๋ฅผ ๋Œ€์ฒดํ•ฉ๋‹ˆ๋‹ค.
        const regex = new RegExp(`src=${index + 1}`, 'g');
        parsedQuestion = parsedQuestion.replace(regex, `src="${imageUrl}"`);
      });
    }

    return parsedQuestion;
  };
 

์•„๋ž˜ ์ฝ”๋“œ๋Š” ๋ณ€๊ฒฝ๋˜ ์ฝ”๋“œ์ด๋‹ค.

 
  const parseImageTag = (question, questionImgUrls) => {
    let parsedQuestion = question;

    // ์ด๋ฏธ์ง€ URL ๋ฐฐ์—ด์ด ์ •์˜๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
    if (Array.isArray(questionImgUrls) && questionImgUrls.length > 0) {
      // ์ด๋ฏธ์ง€ URL ๋ฐฐ์—ด์˜ ๊ฐ ์š”์†Œ๋ฅผ ๋ฐ˜๋ณตํ•˜์—ฌ ์ด๋ฏธ์ง€ ํƒœ๊ทธ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์งˆ๋ฌธ์— ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค.
      questionImgUrls.forEach((imageUrl, index) => {
        // ์ •๊ทœ ํ‘œํ˜„์‹์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฏธ์ง€ ํƒœ๊ทธ๋ฅผ ๋Œ€์ฒดํ•ฉ๋‹ˆ๋‹ค.
        const regex = new RegExp(`src=${index}`, 'g');
        parsedQuestion = parsedQuestion.replace(regex, `src="${imageUrl.url}"`);
      });
    }

    return parse(parsedQuestion);
  };
 

์—ฌ๊ธฐ์„œ ์šฐ๋ฆฌ๊ฐ€ ์ฃผ์˜ ๊นŠ๊ฒŒ ๋ด์•ผํ•  ์ฝ”๋“œ๊ฐ€ ์žˆ๋‹ค. ๊ทธ๊ฒƒ์€ RegExp์ด๋‹ค. ์ •๊ทœ ํ‘œํ˜„์‹์€  ๋ฌธ์ž์—ด์—์„œ ํŠน์ • ๋‚ด์šฉ์„ ์ฐพ๊ฑฐ๋‚˜ ๋Œ€์ฒด ๋˜๋Š” ๋ฐœ์ทŒํ•˜๋Š”๋ฐ ์‚ฌ์šฉํ•œ๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด ์™œ RegExp๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ผ๊นŒ? ๋‹จ์ˆœ ๋ฆฌํ„ฐ๋Ÿด๋กœ ํ‘œํ˜„ํ•ด์„œ ๋ฌธ์ž์—ด ๋ฐฉ์‹์œผ๋กœ ์ž‘์„ฑํ•ด๋„ ๋˜๋Š”๋ฐ ๋ง์ด๋‹ค. RegExp๋Š” ์ƒ์„ฑ์ž์ด๋ฉฐ new๋ฅผ ํ†ตํ•ด์„œ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ๋‹ค. ์ƒ์„ฑ์ž๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ •๊ทœ ํ‘œํ˜„์‹์ด ๋Ÿฐํƒ€์ž„์— ์ปดํ”ผ์ผ์ด ๋œ๋‹ค. ํŒจํ„ด์ด ๋ณ€ํ•  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๊ฑฐ๋‚˜ ์‚ฌ์šฉ์ž ์ž…๋ ฅ์„ ํ•ด์„œ ์ง€์†์ ์œผ๋กœ ์•Œ ์ˆ˜ ์—†๋Š” ์™ธ๋ถ€ ์†Œ์Šค์—์„œ ๊ฐ€์ ธ์˜ค๋Š” ์ •๊ทœ ํ‘œํ˜„์‹์˜ ๊ฒฝ์šฐ ์ƒ์„ฑ์ž๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด ์˜๋ฌธ์ด ๋“ค ๊ฒƒ์ด๋‹ค. ๊ณผ์—ฐ ์šฐ๋ฆฌ์˜ api์—์„  ํŒจํ„ด์ด ๋™์ ์œผ๋กœ ๋ณ€ํ•˜๋Š” ๊ฒƒ์ธ์ง€ ๋ง์ด๋‹ค. ์šฐ์„  ๋ฆฌํ„ธ๋Ÿฌ๋กœ ์œ„์˜ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑ ํ–ˆ์„ ๋•Œ ์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ณด์ž.


const parseImageTag = (question, questionImgUrls) => {
  let parsedQuestion = question;

  // ์ด๋ฏธ์ง€ URL ๋ฐฐ์—ด์ด ์ •์˜๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
  if (Array.isArray(questionImgUrls) && questionImgUrls.length > 0) {
    // ์ด๋ฏธ์ง€ URL ๋ฐฐ์—ด์˜ ๊ฐ ์š”์†Œ๋ฅผ ๋ฐ˜๋ณตํ•˜์—ฌ ์ด๋ฏธ์ง€ ํƒœ๊ทธ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์งˆ๋ฌธ์— ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค.
    questionImgUrls.forEach((imageUrl) => {
      // ์ •๊ทœ ํ‘œํ˜„์‹ ๋ฆฌํ„ฐ๋Ÿด์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฏธ์ง€ ํƒœ๊ทธ๋ฅผ ๋Œ€์ฒดํ•ฉ๋‹ˆ๋‹ค.
      const regex = /src=\d+/g;
      parsedQuestion = parsedQuestion.replace(regex, `src="${imageUrl.url}"`);
    });
  }
  return parse(parsedQuestion);
};

์œ„์™€ ๊ฐ™์ด ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด๋„ ํฌ๊ฒŒ ๋ฌธ์ œ๋Š” ์—†๋‹ค. ๋”ฐ๋ผ์„œ ์šฐ๋ฆฌ๋Š” ๋™์  ๊ธฐ์ค€์œผ๋กœ ๋ฆฌํ„ฐ๋Ÿด๊ณผ ์ƒ์„ฑ์ž๋ฅผ ์ •ํ•˜๋Š” ๊ฒƒ์ด ๋งž๋‹ค ํŒ๋‹จ์ด ๋œ๋‹ค. ๊ทธ๋ž˜์„œ ๋ฆฌํ„ฐ๋Ÿด๋กœ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ์ด ์ข‹๋‹ค๊ณ  ํŒ๋‹จ ๋œ๋‹ค.


* ์ฝ”๋“œ ๋ถ„์„

(์ฝ”๋“œ ๋ถ„์„์„ ํ†ตํ•ด์„œ ๋ณ€์ˆ˜๋ช…๊ณผ ํ•จ์ˆ˜๋ช…์„ ์ˆ˜์ •ํ•ด ๋‚˜๊ฐˆ ๊ฒƒ์ด๋‹ค.)

# ParseImageTag

 
  import parse from 'html-react-parser';
  ...
  // inside ์ด๋ฏธ์ง€ ํŒŒ์‹ฑ ํ›„ ๋ Œ๋”๋ง ํ•จ์ˆ˜ ์ˆ˜์ •
  const parseImageTag = (question, questionImgUrls) => {
    let parsedQuestion = question;

    // ์ด๋ฏธ์ง€ URL ๋ฐฐ์—ด์ด ์ •์˜๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
    if (Array.isArray(questionImgUrls) && questionImgUrls.length > 0) {
      // ์ด๋ฏธ์ง€ URL ๋ฐฐ์—ด์˜ ๊ฐ ์š”์†Œ๋ฅผ ๋ฐ˜๋ณตํ•˜์—ฌ ์ด๋ฏธ์ง€ ํƒœ๊ทธ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์งˆ๋ฌธ์— ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค.
      questionImgUrls.forEach((imageUrl) => {
        // ์ •๊ทœ ํ‘œํ˜„์‹ ๋ฆฌํ„ฐ๋Ÿด์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฏธ์ง€ ํƒœ๊ทธ๋ฅผ ๋Œ€์ฒดํ•ฉ๋‹ˆ๋‹ค.
        const regex = /src=\d+/g;
        parsedQuestion = parsedQuestion.replace(regex, `src="${imageUrl.url}"`);
      });
    }
    return parse(parsedQuestion);
  };
 

 ์ด ํ•จ์ˆ˜์˜ ๋ชฉ์ ์„ ์‚ดํŽด๋ณด๋ฉด api์—์„œ ๋ฌธ์ œ๋ฅผ ๋ถˆ๋Ÿฌ์˜ฌ ๋•Œ ์ด๋ฏธ์ง€ ๋งˆํ‚น์œผ๋กœ ํ‘œ๊ธฐํ•ด๋‘” HTML๋ฌธ๋ฒ•์„ ํŒŒ์‹ฑํ•˜๋Š” ์—ญํ• ์„ ํ•œ๋‹ค. ์ด๋ฏธ์ง€ ๋งˆํ‚น์„ ํ•ด๋‘” ํ‘œ๊ธฐ๋Š” '<img src=0>' ์—์„œ 'src=n' ๋ถ€๋ถ„์„ ํŒŒ์‹ฑํ•ด์„œ ๊ฑฐ๊ธฐ์— ํ•ด๋‹น ๋˜๋Š” api ์ด๋ฏธ์ง€ ๊ฐ์ฒด๋ฅผ ๋Œ€์ฒดํ•˜๋Š” ํ•จ์ˆ˜์ด๋‹ค. ์ฆ‰, ์‚ฝ์ž…๋˜์–ด ์žˆ๋Š” ์ด๋ฏธ์ง€๋ฅผ ๋ Œ๋”๋ง ํ•  ์ˆ˜ ์žˆ๋Š” ํ•จ์ˆ˜์ด๋‹ค. 

๋งค๊ฐœ๋ณ€์ˆ˜ ๋ถ€ํ„ฐ ์‚ดํŽด๋ณด์ž. ์šฐ๋ฆฌ๋Š” ๋‘๊ฐœ์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๊ฐ€์ ธ์™€์•ผํ•œ๋‹ค. ์ฒซ ๋ฒˆ์งธ๋กœ๋Š” ํ•ด๋‹น question ํ•„๋“œ์ธ ๋ฌธ์ œ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ์ด๊ณ  ๋‘ ๋ฒˆ์งธ๋กœ๋Š” question_images_in ํ•„๋“œ๋ฅผ ๊ฐ€์ ธ์™€์„œ ์ด๋ฏธ์ง€ ํ•„๋“œ๋ฅผ ๊ฐ€์ง€๊ณ  ์˜ค๋Š” ๊ฒƒ์ด๋‹ค. ์ฆ‰, id=n์˜ ํ•ด๋‹น๋˜๋Š” question๊ณผ question_images_in๋“ค์„ ์ˆœ์ฐจ์ ์œผ๋กœ ๋ฐ˜๋ณตํ•œ๋‹ค.

 
 <p>{item.id}. {parseImageTag(item.question, item.question_images_in)}</p>
 

์—ฌ๊ธฐ์„œ ๊ฐ ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์–ด๋””๋กœ ์–ด๋–ป๊ฒŒ ํ˜๋Ÿฌ๊ฐ€๋Š”์ง€ ์‚ดํ‘œ๋ณด์ž.

* let parsedQuestion = question;

์šฐ์„  question์€ paredQuestion์œผ๋กœ ์žฌ์ •์˜๊ฐ€ ๋œ๋‹ค. ์›๋ณธ์€ ์œ ์ง€ํ•˜๊ณ  question์ด ๋ณต์‚ฌ๋œ ๊ฐ’์œผ๋กœ replace๋ฅผ ํ•ด์„œ ์ด๋ฏธ์ง€๊ฐ€ ๋ Œ๋”๋ง ๋  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๊ธฐ์œ„ํ•จ์ด๋‹ค. 

* if (Array.isArray(questionImgUrls) && questionImgUrls.length > 0) {...}

ํ•ด๋‹น ์กฐ๊ฑด ๋ฌธ์€ questionImgUrls์— ๋‹ด๊ธด tiem.question_images_in ํ•„๋“œ๊ฐ€ ๋ฐฐ์—ด๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ๋Š”์ง€ ์œ ํšจ์„ฑ์„ ํ™•์ธํ•˜๋Š” ์กฐ๊ฑด ๋ฌธ์ด๋‹ค. ๋งŒ์•ฝ ์œ ํšจํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ๋‹ค๋ฅธ ์ด๋ฏธ์ง€๋กœ ๋Œ€์ฒด๊ฐ€ ๋  ์ˆ˜ ์žˆ๊ฒŒ ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๋ฌผ๋ก  ํ˜„์žฌ๋Š” else๋ฌธ์œผ๋กœ return์ด ๋  ๋•Œ null์„ ์ถœ๋ ฅํ•˜๊ฒŒ ๋œ๋‹ค. ์ด ์กฐ๊ฑด๋ฌธ์€ ์œ ํšจ์„ฑ์„ ํ™•์ธํ•˜๋Š” ์ฐจ์›์—๋„ ์žˆ์ง€๋งŒ ์šฐ๋ฆฌ๊ฐ€ ๋ฐ›์•„์˜ค๋Š” api์˜ ํ•„๋“œ๊ฐ€ ๋ฌธ์ œ๊ฐ€ ๋˜์—ˆ๊ฑฐ๋‚˜ ์˜ˆ๊ธฐ์น˜ ๋ชปํ•œ ์ƒํ™ฉ์„ ๋Œ€๋น„ํ•˜๊ธฐ ์œ„ํ•ด์„œ ํ•„์š”ํ•œ ์กฐ๊ฑด ๋ฌธ์ด๋‹ค. (์˜ˆ์™ธ์  ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์•ผํ•˜๋Š” ๋ถ€๋ถ„์—์„œ FE์—์„œ ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์•ผํ• ์ง€ ๋…ผ์˜ ํ›„์— ์ถ”๊ฐ€์ ์œผ๋กœ ํฌ์ŠคํŒ… ํ•  ์˜ˆ์ •์ด๋‹ค.)

* questionImgUrls.forEach((imageUrl, index) => {..} / const regex = /src=\d+/g; /  parsedQuestion = parsedQuestion.replace(regex, `src="${imageUrl.url}"`); / return parse(parsedQuestion);

์ด์ œ ์œ ํšจ์„ฑ์ด ํ™•์ธ๋œ questionImgUrls ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” forEach๋ฅผ ํ†ตํ•ด์„œ ํ•ด๋‹น ์ด๋ฏธ์ง€ ๋ฐฐ์—ด ์•ˆ์— ์žˆ๋Š” ์š”์†Œ๋“ค์„ ์ฐจ๋ก€๋Œ€๋กœ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฐ›์•„์™€ ์ ์ ˆํžˆ ํ•„์š”ํ•œ ์œ„์น˜์— ์ˆœ์„œ๋Œ€๋กœ ์œ„์น˜์‹œํ‚จ๋‹ค. map ํ•จ์ˆ˜๋Š” ์ƒˆ๋กœ์šด ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜ํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์—ฌ๊ธฐ์— ์‚ฌ์šฉ๋˜๊ธฐ์—๋Š” ์ ์ ˆ์น˜๊ฐ€ ์•Š๋‹ค. ๋”ฐ๋ผ์„œ ์ด๋ฏธ์ง€์˜ ๊ฐ์ฒด๋“ค์„ ์ˆœ์„œ๋Œ€๋กœ ๋ฐ˜๋ณตํ•˜๋Š” ๊ฒƒ์ด ํ•ด๋‹น ํ•จ์ˆ˜์˜ ๋ชฉ์ ์ด๊ธฐ ๋•Œ๋ฌธ์— forEach๋ฌธ์ด ์ ์ ˆํ•œ ๊ฒƒ์ด๋‹ค. regex๋ณ€์ˆ˜๋Š” ์šฐ๋ฆฌ๊ฐ€ ํ•ด๋‹น question์— ๋“ค์–ด ์žˆ๋Š” ์ด๋ฏธ์ง€ ๋งˆํ‚น ๋ถ€๋ถ„์„ ์ •๊ทœ์‹์œผ๋กœ ํŒŒ์‹ฑํ•˜๋Š” ๋ณ€์ˆ˜๋ฅผ ๋‹ด๊ณ  ์žˆ๋‹ค. ํ•ด๋‹น ์ด๋ฏธ์ง€ ๋งˆํ‚น์„ ์ฐพ์•„์„œ ์•ž์„œ question์ด ๋ณต์‚ฌ๋œ parsedQuestion ๋ณ€์ˆ˜์— replace๋ฅผ ํ†ตํ•ด์„œ ์ด๋ฏธ์ง€ ํƒœ๊ทธ์— url์„ ์ ์ ˆํžˆ ๋„ฃ์–ด ์ค€๋‹ค. ์ดํ›„ html-react-parser ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆด ์ƒ์šฉํ•ด์„œ ํ•ด๋‹น question ๊ฐ์ฒด๋ฅผ html๋กœ ๋ Œ๋”๋ง ๋˜๊ฒŒ return๋ฌธ์œผ๋กœ ๋ฐ˜ํ™˜ํ•ด์ค€๋‹ค.

## ๋ณ€์ˆ˜๋ช… ์ˆ˜์ • ์‚ฌํ•ญ

์šฐ๋ฆฌ๊ฐ€ ๋ณ€์ˆ˜๋ช…์„ ๊ณ ๋ฏผ์„ ํ•ด๋ด์•ผ ํ•˜๋Š” ์ด์œ ๋Š” ์•ž์œผ๋กœ ํ•ด๋‹น ํ•จ์ˆ˜๋ฅผ ์™ธ๋ถ€๋กœ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋‘๊ณ  ์žฌ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•  ๊ฒƒ์ด๋‹ค. ์ฆ‰, ํ˜„์žฌ ๋งค๊ฐœ๋ณ€์ˆ˜๋งŒ ๋ณด์•„๋„ question์ด๋ผ๋“ ๊ฐ€ questionImgUrls์™€ ๊ฐ™์€ ๋ณ€์ˆ˜๋ช…์€ ํ˜„์žฌ ์Šคํฌ๋ฆฝํŠธ ์ค‘์‹ฌ์œผ๋กœ ๋ณด์•˜์„ ๋• ๊ดœ์ฐฎ์•„ ๋ณด์ด๋‚˜ ์žฌ์‚ฌ์šฉ ์—ฌ๋ถ€๋ฅผ ๋‘๊ณ  ๋ณด์•˜์„ ๋•Œ๋Š” ๊ณผ์—ฐ ์ ์ ˆํ•œ ๋ณ€์ˆ˜๋ช…์ธ์ง€ ๊ณ ๋ฏผ์„ ํ•˜๊ฒŒ ๋œ๋‹ค. ์ฆ‰, ํ•ด์„ค๋ถ€๋ถ„์—์„œ๋„ ํ•ด๋‹น ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋Š”๋ฐ question์ด๋ผ๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ๋„ˆ๋ฌด ์ œํ•œ์  ์˜๋ฏธ ์ค‘์‹ฌ์ ์ด๋ž€ ์ƒ๊ฐ์ด ๋“ ๋‹ค. ๊ทธ๋ž˜์„œ element๋‚˜ item๊ณผ ๊ฐ™์€ ๋‹จ์–ด๋กœ ํ†ตํ•ฉ์ ์ธ ์˜๋ฏธ๋กœ ์ž‘๋ช…์„ ํ• ์ง€ ๊ณ ๋ฏผ ์ค‘์ด๋‹ค. ๋”ฐ๋ผ์„œ ๋‹ค๋ฅธ ํ”„๋กœ์ ํŠธ๋“ค์˜ ํ•จ์ˆ˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋“ค์„ ์ฐพ์•„์„œ ์ฐธ๊ณ ํ•ด๋ฉด ์ข‹์„ ๋“ฏ ํ•˜๋‹ค. ๋” ๋‚˜์•„๊ฐ€ ํ•จ์ˆ˜๋ช… ๋˜ํ•œ ์žฌ์ •์˜ ํ•˜๋ฉด ์ข‹์„ ๋“ฏ ํ•˜๋‹ค. imageUrl๊ฐ™์€ ๊ฒฝ์šฐ์—๋„ ํ˜„์žฌ๋Š” ์šฐ๋ฆฌ๊ฐ€ imageUrl์—์„œ url๋งŒ ์ ์šฉํ•˜์ง€๋งŒ ์ดํ›„์— class์ด๋ฆ„์„ ์ ‘๊ทผํ•˜๋Š” attibute์™€ ๊ฐ™์€ ๊ฐ์ฒด๋ฅผ ์ ‘๊ทผํ•ด์•ผ ํ•œ๋‹ค. ๊ทธ๋•Œ๋ฅผ ์ƒ๊ฐํ•ด์„œ ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ ๋ณด๋ฉด imageUrl๊ฐ™์€ ๋ณ€์ˆ˜๋ช…์€ ๋ฒ”์œ„๊ฐ€ ๋„ˆ๋ฌด ์ข๋‹ค๊ณ  ๋ณธ๋‹ค. parseImageTag๋ผ๊ณ  ์ž‘๋ช…ํ•˜๋Š” ๊ฒƒ๋„ ์ข‹์ง€๋งŒ ์•„๋ž˜ renderImage์™€ ๋Œ€์กฐ ํ•ด๋ณด์•˜์„ ๋•Œ ๋„ˆ๋ฌด ๋™๋–จ์–ด์ง„ ํ•จ์ˆ˜๊ฐ™์•„ ๋ณด์—ฌ ์ˆ˜์ •์ด ํ•„์š”ํ•ด ๋ณด์ธ๋‹ค.


# renderImages

 
 // outside ์ด๋ฏธ์ง€ ๋ Œ๋”๋ง ํ•จ์ˆ˜ ์ˆ˜์ •
  const renderImages = (imageData) => {
    if (Array.isArray(imageData) && imageData.length > 0) {
      return imageData.map((image, index) => (
        <img
          key={index}
          src={image.url} // ์ด๋ฏธ์ง€ ๊ฐ์ฒด์—์„œ URL์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
          alt={`Image ${index}`}
          style={{ width: '100%' }}
        />
      )) ;
    } else {
      return null;
    }
  };
 

 ์ด ํ•จ์ˆ˜์˜ ๋ชฉ์ ์„ ์‚ดํŽด๋ณด๋ฉด api์—์„œ ์™ธ๋ถ€์— ์žˆ๋Š” ์ด๋ฏธ์ง€๋ฅผ ๋ Œ๋”๋ง ํ•˜๋Š” ์—ญํ• ์„ ํ•œ๋‹ค. ์™ธ๋ถ€์˜ ์ด๋ฏธ์ง€๋ฅผ imgํƒœ๊ทธ๋ฅผ ํ†ตํ•ด์„œ ๋ Œ๋”๋งํ•˜๋Š” ๋ชฉ์ ์œผ๋กœ ๋งŒ๋“ค์–ด์ง„ ํ•จ์ˆ˜๋ผ์„œ ์ด์ „ ParserImageTag์™€ ๋‹ฌ๋ฆฌ ํŠน๋ณ„ํžˆ ํŒŒ์‹ฑ์„ ํ•˜์ง€๋Š” ์•Š๋Š”๋‹ค. ์ฝ”๋“œ์˜ ํ˜•ํƒœ๋Š” ์ด์ „ ์ฝ”๋“œ์™€ ๋งค์šฐ ์œ ์‚ฌํ•˜๋‹ค.

 
<div>{renderImages(item.question_images_out)}</div>
 

* if (Array.isArray(questionImgUrls) && questionImgUrls.length > 0) {...}

์•ž์„œ ํ™•์ธ ํ–ˆ๋˜ ํ•จ์ˆ˜์˜ ๋ฐฐ์—ด ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ํ•˜๋Š” ์กฐ๊ฑด๋ฌธ์€ ๋™์ผํ•˜๋ฉฐ tiem.question_images_out ํ•„๋“œ๊ฐ€ ๋ฐฐ์—ด๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ์กฐ๊ฑด ๋ฌธ์ด๋‹ค. ์œ„์˜ ํ•จ์ˆ˜์™€ ๋™์ผํ•˜๊ฒŒ ๋งŒ์•ฝ ์œ ํšจํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด else๋ฌธ์œผ๋กœ return์ด ๋  ๋•Œ null์„ ์ถœ๋ ฅํ•˜๊ฒŒ ๋œ๋‹ค. (์˜ˆ์™ธ์  ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์•ผํ•˜๋Š” ๋ถ€๋ถ„์—์„œ FE์—์„œ ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์•ผํ• ์ง€ ๋…ผ์˜ ํ›„์— ์ถ”๊ฐ€์ ์œผ๋กœ ํฌ์ŠคํŒ… ํ•  ์˜ˆ์ •์ด๋‹ค.)

* return imageData.map((image, imageIndex) => (...)

์—ฌ๊ธฐ์„œ๋Š” forEach๊ฐ€ ์•„๋‹ˆ๋ผ mapํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ฐ€์ ธ์˜จ ๋ฐฐ์—ด์„ imgํƒœ๊ทธ ์š”์†Œ๋ฅผ ์ƒ์„ฑํ•ด์„œ ์ƒˆ๋กœ์šด ๋ฐฐ์—ด์„ ๋งŒ๋“ค์–ด ๋‚ด๋Š” ๊ฒƒ์ด๋‹ค. ์ฆ‰, ์ด์ „์— ์šฐ๋ฆฌ๊ฐ€ ์‚ดํŽด๋ณธ ParseImageTagํ•จ์ˆ˜๋Š” ๋ฐฐ์—ด์˜ ์š”์†Œ๋ฅผ ๋‹จ์ˆœํžˆ ์ˆœ์„œ๋Œ€๋กœ ๋‚˜์—ดํ•˜๊ณ  replace ํ•˜๋Š” ์ •๋„์ด๊ธฐ ๋•Œ๋ฌธ์— forEach๋ฌธ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ ํ•ฉํ–ˆ๋‹ค. ๋”ฐ๋ผ์„œ renderImageํ•จ์ˆ˜์—์„œ๋Š” imgํƒœ๊ทธ ์š”์†Œ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ƒˆ๋กœ์šด ๋ฐฐ์—ด์„ ๋งŒ๋“ค์–ด๋‚ด๋Š” ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ์—ฌ๊ธฐ์„œ๋Š” mapํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ ์ ˆํ•˜๋‹ค.

## ๋ณ€์ˆ˜๋ช… ์ˆ˜์ • ์‚ฌํ•ญ

๋ณ€์ˆ˜๋ช… ์ˆ˜์ • ํ•ด์•ผ ํ•  ๋ถ€๋ถ„์€ imageData ๋งค๊ฐœ๋ณ€์ˆ˜์ด๋‹ค. image์˜ ๋”ฐ๋ฅธ data๋Š” ๋งž์ง€๋งŒ ํ•ด๋‹น ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” api์˜ ํ•„๋“œ๋ช…์„ ๊ฐ€์ ธ์˜ค๊ธฐ ๋•Œ๋ฌธ์— image๋ผ๊ณ  ํŠน์ • ์ง“๋Š” ๊ฒƒ์€ ์žฌํ™œ์šฉ์„ ํ•˜๊ธฐ ์žˆ์–ด์„œ ๋‹จ์–ด์˜ ๋ฒ”์œ„๊ฐ€ ๋น„์ข์€ ๊ฐ์ด ์—†์ง€ ์•Š์•„ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ด ๋˜ํ•œ item์ด๋‚˜ element์™€ ๊ฐ™์€ ๊ด‘๋ฒ”์œ„ํ•œ ๋‹จ์–ด๋ฅผ ์„ ํƒํ•˜๋Š” ๊ฒƒ์ด ์ข‹์„ ๊ฒƒ๊ฐ™๋‹ค. ๋˜๋Š” filedName์ด๋ผ๊ณ  ์ž‘์„ฑํ•˜๋ฉด ์–ด๋–จ๊นŒ? renderImageํ•จ์ˆ˜๋ช… ๋˜ํ•œ ์ˆ˜์ •์ด ํ•„์š”ํ•ด ๋ณด์ธ๋‹ค. image๊ฐ€ render๋˜๋Š” ๊ฒƒ์€ ๋งž์ง€๋งŒ parseImageTag์™€ ๋น„๊ตํ•ด ๋ณด๋ฉด ์กฐ๊ธˆ์€ ์–ด์ƒ‰ํ•ด ๋ณด์ธ๋‹ค.

728x90
Comments