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

C-log

[FE]๋‚˜๋งŒ์˜ ์‹œํ—˜์ง€์˜ ์—๋””ํ„ฐ์™€ ํˆด๋ฐ”๋ฅผ ์ง์ ‘ ์ œ์ž‘ํ•œ๋‹ค.(์ด๋ฏธ์ง€ ์ฒจ๋ถ€ ํˆด๋ฐ” ์ œ์ž‘) ๋ณธ๋ฌธ

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

[FE]๋‚˜๋งŒ์˜ ์‹œํ—˜์ง€์˜ ์—๋””ํ„ฐ์™€ ํˆด๋ฐ”๋ฅผ ์ง์ ‘ ์ œ์ž‘ํ•œ๋‹ค.(์ด๋ฏธ์ง€ ์ฒจ๋ถ€ ํˆด๋ฐ” ์ œ์ž‘)

4:Bee 2024. 3. 24. 00:51
728x90
 
  const [imageFiles, setImageFiles] = useState([]); // ์ด๋ฏธ์ง€ ํŒŒ์ผ๋“ค์„ ์ €์žฅํ•  ๋ฐฐ์—ด ์ƒํƒœ
  const [imageUrl, setImageUrl] = useState([]);
 
   ...
 
// ์—๋””ํ„ฐ๊ฐ€ ์—…๋ฐ์ดํŠธ๋  ๋•Œ ์ด๋ฏธ์ง€ ์‚ฝ์ž…
  useEffect(() => {
    if (editorRef.current && imageFiles.length > 0) {
      const file = imageFiles[imageFiles.length - 1];
      insertImageDate(file);
    }
  }, [editorRef.current, imageFiles]);


  const handleImageSelect = (e) => {
    const files = e.target.files;
    if (!!files && files.length > 0) {
      const file = files[0];//?
      // ์ด๋ฏธ์ง€ ํŒŒ์ผ ๋ฐฐ์—ด์— ์ถ”๊ฐ€
      setImageFiles([...imageFiles, file]);

      handleSave();
    }
  };

  //์ด๋ฏธ์ง€๋ฅผ ์‚ฝ์ž…ํ•˜๊ณ  ๋ Œ๋”๋งํ•˜๋Š” ํ•จ์ˆ˜
  const insertImageDate = (file) => {
    const reader = new FileReader();
    reader.onload = function (e) {
      const imageDataUrl = e.target.result;
      // ์ด๋ฏธ์ง€๋ฅผ ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค.
      const imgElement = document.createElement('img');
      imgElement.src = imageDataUrl;
      setImageUrl([...imageUrl, imgElement.src]);
      // editorRef๊ฐ€ null์ด ์•„๋‹Œ ๊ฒฝ์šฐ์—๋งŒ ์ด๋ฏธ์ง€๋ฅผ ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค.
      if (editorRef.current) {
        editorRef.current.appendChild(imgElement);
      } else {
        console.error("Editor reference is null.");
      }
    };
    reader.readAsDataURL(file);
  };

* handleImageSelect

์œ„์˜ ์ฝ”๋“œ๋Š” ์ด๋ฏธ์ง€๋ฅผ ์„ ํƒํ•˜๊ณ  ํŒŒ์ผ์ด ์„ ํƒ๋˜๋ฉด ํ•ด๋‹น ํŒŒ์ผ์„ ์ด๋ฏธ์ง€ ํŒŒ์ผ ๋ฐฐ์—ด์— ์ถ”๊ฐ€ํ•˜๊ณ  handleSave ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.

๋”๋ณด๊ธฐ
 
  const handleImageSelect = (e) => {
    const files = e.target.files;
    if (!!files && files.length > 0) {
      const file = files[0];//?
      // ์ด๋ฏธ์ง€ ํŒŒ์ผ ๋ฐฐ์—ด์— ์ถ”๊ฐ€
      setImageFiles([...imageFiles, file]);
      handleSave();
    }
  };
 


ํŒŒ์ผ ์„ ํƒ <input> ์š”์†Œ๋ฅผ ํด๋ฆญํ•˜์—ฌ ํŒŒ์ผ์„ ์„ ํƒํ•˜๋Š” ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ฒŒ ๋˜๋ฉด ํŒŒ์ผ ์„ ํƒ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๊ณ  handleImageSelect ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค.

 
  <input
  type="file"
  accept="image/*"
  style={{ display: 'none' }}
  ref={imageSelectorRef}
  onChange={handleImageSelect}
/>
 

 

* const files = e.target.files;

e.target.files๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉ์ž๊ฐ€ ์„ ํƒํ•œ ํŒŒ์ผ ๋ชฉ๋ก์— ์ ‘๊ทผ์„ ํ•œ๋‹ค.

* if (!!files && files.length > 0) {...}

์„ ํƒ๋œ ํŒŒ์ผ์ด ์กด์žฌํ•˜๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด !!files๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ์ด๊ฒƒ์€ ์„ ํƒ๋œ ํŒŒ์ผ์ด ์กด์žฌํ•˜๋ฉด true๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ , ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด false๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ์„ ํƒ๋œ ํŒŒ์ผ์ด ์กด์žฌํ•˜๊ณ  ํŒŒ์ผ ๋ชฉ๋ก์˜ ๊ธธ์ด๊ฐ€ 0๋ณด๋‹ค ํฐ์ง€ ํ™•์ธํ•œ๋‹ค.

* const file = files[0];

files[0]์„ ํ†ตํ•ด ํŒŒ์ผ ๋ชฉ๋ก์—์„œ ์ฒซ ๋ฒˆ์งธ ํŒŒ์ผ์„ ๊ฐ€์ ธ์˜จ๋‹ค. ์ด๊ฒƒ์€ ๋‹จ์ผ ํŒŒ์ผ ์„ ํƒ์„ ๊ฐ€์ •ํ•œ๋‹ค.

* setImageFiles([...imageFiles, file]);

์ด๋ฏธ์ง€ ํŒŒ์ผ ๋ฐฐ์—ด์— ํ˜„์žฌ ํŒŒ์ผ์„ ์ถ”๊ฐ€ํ•˜๊ธฐ ์œ„ํ•ด spread ์—ฐ์‚ฐ์ž ...๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด์ „ ์ด๋ฏธ์ง€ ํŒŒ์ผ ๋ฐฐ์—ด๊ณผ ์ƒˆ๋กœ์šด ํŒŒ์ผ์„ ๋ณ‘ํ•ฉํ•œ๋‹ค.

* handleSave();

๋งˆ์ง€๋ง‰์œผ๋กœ handleSave ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๋ณ€๊ฒฝ๋œ ์ด๋ฏธ์ง€ ํŒŒ์ผ ๋ฐฐ์—ด์„ ์ €์žฅํ•œ๋‹ค.


* insertImageDate

์œ„์˜ ์ฝ”๋“œ๋Š” ์ด๋ฏธ์ง€ ํŒŒ์ผ์„ ์ฝ๊ณ  ์ด๋ฏธ์ง€๋ฅผ ์‚ฝ์ž…ํ•˜๊ณ  ๋ Œ๋”๋งํ•˜๋Š” ํ•จ์ˆ˜์ด๋‹ค. 

๋”๋ณด๊ธฐ
 
 //์ด๋ฏธ์ง€๋ฅผ ์‚ฝ์ž…ํ•˜๊ณ  ๋ Œ๋”๋งํ•˜๋Š” ํ•จ์ˆ˜
  const insertImageDate = (file) => {
    const reader = new FileReader();
    reader.onload = function (e) {
      const imageDataUrl = e.target.result;
      // ์ด๋ฏธ์ง€๋ฅผ ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค.
      const imgElement = document.createElement('img');
      imgElement.src = imageDataUrl;
      setImageUrl([...imageUrl, imgElement.src]);
      // editorRef๊ฐ€ null์ด ์•„๋‹Œ ๊ฒฝ์šฐ์—๋งŒ ์ด๋ฏธ์ง€๋ฅผ ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค.
      if (editorRef.current) {
        editorRef.current.appendChild(imgElement);
      } else {
        console.error("Editor reference is null.");
      }
    };
    reader.readAsDataURL(file);
  };
 

 

* const insertImageDate = (file) => { const reader = new FileReader(); ...}

insertImageDate ํ•จ์ˆ˜๋Š” ํŒŒ์ผ์„ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฐ›๋Š”๋‹ค. ์ด ํŒŒ์ผ์€ ์ด๋ฏธ์ง€ ํŒŒ์ผ์ด๋‹ค. ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉด, FileReader ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ฉํ•œ๋‹ค. ์ด ๊ฐ์ฒด๋Š” ํŒŒ์ผ์„ ๋น„๋™๊ธฐ์ ์œผ๋กœ ์ฝ๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋œ๋‹ค.

* reader.onload = function (e) { const imageDataUrl = e.target.result; ...}

FileReader ๊ฐ์ฒด์˜ onload ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์„ค์ •ํ•œ๋‹ค. ํŒŒ์ผ์˜ ๋กœ๋”ฉ์ด ์™„๋ฃŒ๋˜๋ฉด ํ•ด๋‹น ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค. ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ๋‚ด์—์„œ๋Š” FileReader์˜ result ์†์„ฑ์„ ํ†ตํ•ด ์ฝ์€ ํŒŒ์ผ์˜ ๋ฐ์ดํ„ฐ url์„ ๊ฐ€์ ธ์˜จ๋‹ค. ๋ฐ์ดํ„ฐ url์€ ํŒŒ์ผ์˜ ๋‚ด์šฉ์„ ๋‚˜ํƒ€๋‚ด๋Š” url์ด๋‹ค.

* const imgElement = document.createElement('img');
      imgElement.src = imageDataUrl;
      setImageUrl([...imageUrl, imgElement.src]);

๊ฐ€์ ธ์˜จ ๋ฐ์ดํ„ฐ์˜ url์„ ์‚ฌ์šฉํ•˜์—ฌ <img> ์š”์†Œ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ด <img> ์š”์†Œ์˜ src ์†์„ฑ์— ๋ฐ์ดํ„ฐ url์„ ์„ค์ •ํ•œ๋‹ค. ์ƒˆ๋กœ์šด ์ด๋ฏธ์ง€ url์„ ์ด๋ฏธ์ง€ url ๋ฐฐ์—ด์— ์ถ”๊ฐ€ํ•œ๋‹ค. ์ด ๋ฐฐ์—ด์€ ์ด๋ฏธ์ง€ url๋“ค์„ ์ถ”์ ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋œ๋‹ค.

*  if (editorRef.current) {
        editorRef.current.appendChild(imgElement);
      } else {
        console.error("Editor reference is null.");
      }

๋งŒ์•ฝ editorRef๊ฐ€ null์ด ์•„๋‹ˆ๋ผ๋ฉด ์ด๋ฏธ์ง€๋ฅผ ์‚ฝ์ž…ํ•  ํŽธ์ง‘๊ธฐ ์š”์†Œ์— ์ด๋ฏธ์ง€๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด ์ƒ์„ฑ๋œ <img> ์š”์†Œ๋ฅผ ํ•ด๋‹น ํŽธ์ง‘๊ธฐ ์š”์†Œ์— ์ถ”๊ฐ€ํ•œ๋‹ค. ๋งŒ์•ฝ editorRef๊ฐ€ null์ด๋ผ๋ฉด ์ฝ˜์†”์— "Editor reference is null."์ด๋ผ๋Š” ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.


* useEffect(()=>...)

์œ„์˜ ์ฝ”๋“œ๋Š” useEffect ํ›…์„ ์‚ฌ์šฉํ•˜์—ฌ ํŽธ์ง‘๊ธฐ๊ฐ€ ์—…๋ฐ์ดํŠธ๋  ๋•Œ ์ด๋ฏธ์ง€๋ฅผ ์‚ฝ์ž…ํ•˜๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.

๋”๋ณด๊ธฐ
 
// ์—๋””ํ„ฐ๊ฐ€ ์—…๋ฐ์ดํŠธ๋  ๋•Œ ์ด๋ฏธ์ง€ ์‚ฝ์ž…
 useEffect(() => {
  if (editorRef.current && imageFiles.length > 0) {
    const file = imageFiles[imageFiles.length - 1];
    insertImageDate(file);
  }
 }, [editorRef.current, imageFiles]);
 


useEffect ํ›…์€ ํ•จ์ˆ˜๋ฅผ ์ปดํฌ๋„ŒํŠธ์˜ ๋ Œ๋”๋ง ๊ฒฐ๊ณผ๋ฌผ์ด ํ™”๋ฉด์— ๋ฐ˜์˜๋œ ํ›„์— ์‹คํ–‰์‹œํ‚จ๋‹ค. ์˜์กด์„ฑ ๋ฐฐ์—ด์— ์žˆ๋Š” ๊ฐ’๋“ค ์ค‘ ํ•˜๋‚˜๋ผ๋„ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ํšจ๊ณผ ํ•จ์ˆ˜๊ฐ€ ๋‹ค์‹œ ์‹คํ–‰๋œ๋‹ค. ์—ฌ๊ธฐ์„œ ์˜์กด์„ฑ ๋ฐฐ์—ด์—๋Š” editorRef.current์™€ imageFiles๊ฐ€ ์žˆ๋‹ค.

* if (editorRef.current && imageFiles.length > 0) {...}

editorRef.current๊ฐ€ ์กด์žฌํ•˜๊ณ , imageFiles ๋ฐฐ์—ด์˜ ๊ธธ์ด๊ฐ€ 0๋ณด๋‹ค ํฐ ๊ฒฝ์šฐ์—๋งŒ ์กฐ๊ฑด๋ฌธ์ด ์‹คํ–‰๋œ๋‹ค.

* const file = imageFiles[imageFiles.length - 1];

์กฐ๊ฑด๋ฌธ ๋‚ด์—์„œ๋Š” imageFiles ๋ฐฐ์—ด์—์„œ ๊ฐ€์žฅ ์ตœ๊ทผ์— ์ถ”๊ฐ€๋œ ์ด๋ฏธ์ง€ ํŒŒ์ผ์„ ๊ฐ€์ ธ์˜จ๋‹ค. ๊ฐ€์ ธ์˜จ ํŒŒ์ผ์„ insertImageDate ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ด๋ฏธ์ง€๋ฅผ ์‚ฝ์ž…ํ•˜๋Š”๋ฐ ์‚ฌ์šฉํ•œ๋‹ค.

์ฆ‰, ์ „์ฒด์ ์œผ๋กœ ํ๋ฆ„์„ ์‚ดํŽด๋ณด๋ฉด handleImageSelect๊ฐ€ ์„ ํƒ์ด ๋˜๊ณ  useEffect๊ฐ€ ์˜์กดํ•˜๊ณ  ์žˆ๋Š” ์˜์กด์„ฑ ๋ฐฐ์—ด์ธ imageFiles์˜ ์ƒํƒœ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜๋ฉด์„œ useEffect๊ฐ€ ์—…๋ฐ์ดํŠธ๊ฐ€ ๋˜๋ฉด์„œ insertImageDate๋กœ ์ด๋ฏธ์ง€๊ฐ€ ์—…๋กœ๋“œ๊ฐ€ ๋˜๋ฉด์„œ appendChild๋ฅผ ํ†ตํ•ด editorRef์— ์ƒ์„ฑ๋œ ์ด๋ฏธ์ง€๋ฅผ ์‚ฝ์ž…ํ•˜๊ณ  ์ž…๋ ฅ๋ž€์˜ div์— ์ด๋ฏธ์ง€๊ฐ€ ์™„์„ฑ์ด ๋˜๋Š” ๊ฒƒ์ด๋‹ค.

728x90
Comments