React 활용 - 6 : 첨부 이미지 파일 미리보기 (react 이미지 미리보기, react state 배열)

2022. 10. 13. 22:29React

반응형

이번에는 지난 시간의 소스를 활용하여 첨부한 이미지를 미리보기로 보는 기능을 만들어 보자.

 

우선 원리는 아래와 같다.

 

1) 첨부 이미지를 버퍼 (base64) 형식으로 변환

2) base64 데이터를 state에 배열 형태로 저장

3) 저장 된 배열 state를 화면에 뿌려줌

 

base64 데이터를 저장 할 배열 state를 선언한다.

 

const [imgBase64, setImgBase64] = useState([]);

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

function FileData() {
  const [file, setFile] = useState(null);	//파일	
  const [imgBase64, setImgBase64] = useState([]); // 파일 base64
  const handleChangeFile = (event) => {
  
    setFile(event.target.files);
  }

  function Send(){
    const fd = new FormData();
    Object.values(file).forEach((file) => fd.append("file", file));

   
    axios.post('/test/AxiosFileTest.do', fd, {
      headers: {
        "Content-Type": `multipart/form-data; `,
      },
      baseURL: 'http://localhost:8080'
    })
    .then((response) => {
      
    })
    .catch((error) => {
      // 예외 처리
    })
  
  }
    return (
        <div>
            FileData
            <div>
                fileData1:  <input type="file" id="file" onChange={handleChangeFile} multiple="multiple"></input>
            </div>
           
            <div>
                <button onClick={()=> Send()}>Send</button>
            </div>
        </div>
    );
  }
export default FileData;
FileReader의 readAsDataURL을 사용하여 받아온 파일을 버퍼 형태로 변환하여 저장 가능하다.
 

버퍼 저장 후 동작을 아래 코드를 통해 지정 가능하다.

 
 reader.onloadend = () => { }
해당 코드를 통해 버퍼 저장 후 state에 배열 형태로 base64 데이터를 저장한다.
const base64 = reader.result;

if (base64) {
        var base64Sub = base64.toString()
        setImgBase64(imgBase64 => [...imgBase64, base64Sub]); }

 

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

function FileData() {
  const [file, setFile] = useState(null);	//파일	
  const [imgBase64, setImgBase64] = useState([]); // 파일 base64
  const handleChangeFile = (event) => {
    setFile(event.target.files);
    setImgBase64([]);
    
    for(var i=0;i<event.target.files.length;i++){
      if (event.target.files[i]) {
        let reader = new FileReader();
        reader.readAsDataURL(event.target.files[i]); // 1. 파일을 읽어 버퍼에 저장.
        // 파일 상태 업데이트
        reader.onloadend = () => {
          // 2. 읽기가 완료되면 아래코드가 실행.
          const base64 = reader.result;
          if (base64) {
          // 문자 형태로 저장
          var base64Sub = base64.toString()
          // 배열 state 업데이트
          setImgBase64(imgBase64 => [...imgBase64, base64Sub]);
          }
        }
      }
    }

  }

  function Send(){
    const fd = new FormData();
    Object.values(file).forEach((file) => fd.append("file", file));

   
    axios.post('/test/AxiosFileTest.do', fd, {
      headers: {
        "Content-Type": `multipart/form-data; `,
      },
      baseURL: 'http://localhost:8080'
    })
    .then((response) => {
      
    })
    .catch((error) => {
      // 예외 처리
    })
  
  }
    return (
        <div>
            FileData
            <div>
                fileData1:  <input type="file" id="file" onChange={handleChangeFile} multiple="multiple"></input>
            </div>
         
            <div>
                <button onClick={()=> Send()}>Send</button>
            </div>
        </div>
    );
  }
export default FileData;

 

반응형

이제 저장한 base64 데이터를 화면에 뿌려주면 된다.

 

배열 형태이기 때문에 map을 사용하여 뿌려준다.

 

 {imgBase64.map((item) => {return <img src={item} style={{maxHeight:"300px",maxWidth:"300px"}}></img>})}
import React, { useState, useEffect } from 'react';
import axios from 'axios'; 

function FileData() {
  const [file, setFile] = useState(null);	//파일	
  const [imgBase64, setImgBase64] = useState([]); // 파일 base64
  const handleChangeFile = (event) => {
    console.log(event.target.files)
    setFile(event.target.files);
    setImgBase64([]);
    
    for(var i=0;i<event.target.files.length;i++){
      if (event.target.files[i]) {
        let reader = new FileReader();
        reader.readAsDataURL(event.target.files[i]); // 1. 파일을 읽어 버퍼에 저장.
        // 파일 상태 업데이트
        reader.onloadend = () => {
          // 2. 읽기가 완료되면 아래코드가 실행.
          const base64 = reader.result;
          if (base64) {
          // 문자 형태로 저장
          var base64Sub = base64.toString()
          // 배열 state 업데이트
          setImgBase64(imgBase64 => [...imgBase64, base64Sub]);
          }
        }
      }
    }

  }

  function Send(){
    const fd = new FormData();
    Object.values(file).forEach((file) => fd.append("file", file));

   
    axios.post('/test/AxiosFileTest.do', fd, {
      headers: {
        "Content-Type": `multipart/form-data; `,
      },
      baseURL: 'http://localhost:8080'
    })
    .then((response) => {
      
    })
    .catch((error) => {
      // 예외 처리
    })
  
  }
    return (
        <div>
            FileData
            <div>
                fileData1:  <input type="file" id="file" onChange={handleChangeFile} multiple="multiple"></input>
            </div>
            <div>
              <h3>이미지 미리보기 영역</h3>
              {imgBase64.map((item) => {return <img src={item} style={{maxHeight:"300px",maxWidth:"300px"}}></img>})}
            </div>
            
            <div>
                <button onClick={()=> Send()}>Send</button>
            </div>
        </div>
    );
  }
export default FileData;

 

 

아래 영상과 같이 이미지 미리보기가 정상적으로 작동한다.

 

https://youtu.be/6rO9d3T4yNA

 

 

소스코드 보기

 

React 활용 - 6 : 첨부 이미지 파일 미리보기 (react 이미지 미리보기, react state 배열) · sonhoil/reactBootT

Showing 1 changed file with 24 additions and 3 deletions.

github.com

 

반응형