React js에서 이미지 미리보기 만들기

23346 단어 reactjavascript
앱이 추가된 이미지를 서버에 업로드하기 전에 사용자에게 미리보기를 표시하는 것은 멋진 UI 상호 작용입니다. 이 게시물은 React js를 사용하여 이를 달성하는 방법을 설명합니다.

우리는 ImgPrev.js라는 기능적 구성 요소를 사용할 것입니다. 자리 표시자 이미지는 img 태그의 자리 표시자가 되어야 합니다. 또한 마법을 완성하기 위해 CSS 스타일 파일을 가져와야 합니다.
자리 표시자로 사용한 사진입니다(안 보이시면 사진이 하얗기 때문입니다만 믿으세요! 😄).



import React, { useState } from 'react';
import placeholder from '../images/placeholder.png';
import './style.css';

const ImgPrev = () => {
   return(
      <form></form>
   );
}

export default ImgPrev;


이제 해당 스타일시트에 대해 조금 이야기해 보겠습니다.

/* This is used to reset the default styles 
applied to every element in this app */
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

.form__title {
    margin: 32px 0;
    text-align: center;
    color: #002952;
}

.form__img-input-container {
    position: relative;
    width: 300px;
    height: 300px;
    margin: auto;
}

/* this class is used to hide the file input */
.visually-hidden {
    position: absolute;
    height: 1px;
    width: 1px;
    overflow: hidden;
    clip: rect(1px, 1px, 1px, 1px);
}

/* Adding the focus and focus-within styles for accessibility */
input.visually-hidden:focus + label,
input.visually-hidden:focus-within + label {
    outline: 8px solid rgba(86, 206, 239, .4);
}

/* The file input is a labeled control, and since we hid it, 
we're going to use its associated label to trigger it */
.form-img__file-label {
    position: absolute;
    top: 0;
    left: 0;
    display: block;
    width: 300px;
    height: 300px;
    border-radius: 50%;
    cursor: pointer;
    background-color: rgba(245, 245, 231, .3);
}

.form-img__file-label:hover {
    background-color: rgba(245, 245, 231, .5);
}

.form-img__file-label > svg {
    position: absolute;
    top: 50%;
    left: 50%;
    opacity: .7;
    transform: translate(-50%, -50%);
}

.form-img__file-label:hover > svg {
    opacity: 1;
}

/* The image element is going to be positioned under the 
label element, since the label is a see through, we're going 
to be able to see the preview of the image. */
.form-img__img-preview {
    display: block;
    width: 300px;
    height: 300px;
    object-fit: contain;
    border-radius: 50%;
    border: 16px rgb(80, 199, 235) solid;
}


파일 입력을 숨기기 위해 여기에서 언급한 스타일 규칙을 사용했습니다MDN page.

우리 구성 요소는 파일 입력을 포함하는 일부 JSX 코드를 반환할 예정이며 사용자가 레이블을 클릭하고 이미지를 선택(또는 취소)하는 즉시 png, jpg 및 jpeg 유형의 파일만 허용하는 handleImg 메서드 실행되고 img 태그는 사용자가 선택한 이미지를 표시하거나 표시하지 않습니다.

return (
        <form encType="multipart/form-data">
            <h1 className="form__title">Image Preview in Reactjs</h1>
            <div className="form__img-input-container">
                <input 
                    type="file" 
                    accept=".png, .jpg, .jpeg" 
                    id="photo" 
                    className="visually-hidden"
                    onChange={handleImg}

                />
                <label htmlFor="photo" className="form-img__file-label">
                    <svg width="150" height="150" viewBox="0 0 24 24" fill="none" stroke="#56ceef" strokeWidth="1" strokeLinecap="round" strokeLinejoin="round">
                        <path d="M5.52 19c.64-2.2 1.84-3 3.22-3h6.52c1.38 0 2.58.8 3.22 3" />
                        <circle cx="12" cy="10" r="3" />
                        <circle cx="12" cy="12" r="10" />
                    </svg>
                </label>
                <img src={src} alt={alt} className="form-img__img-preview"/>
            </div>
        </form>
    );


이미지가 표시되도록 하려면 상태를 사용하여 저장해야 하며 이렇게 하면 모든 상태 업데이트에서 구성 요소가 다시 렌더링되고 발생할 때마다 구성 요소가 선택한 이미지를 미리 볼 수 있습니다.
우리 상태는 이미지 태그의 src 및 alt 속성을 저장하고 기본값으로 자리 표시자와 '이미지 업로드'를 갖습니다.

const [{alt, src}, setImg] = useState({
        src: placeholder,
        alt: 'Upload an Image'
});


handleImg 메서드에서 먼저 사용자가 이미지를 선택했는지 여부를 확인해야 합니다. 그렇지 않으면 다음 오류가 표시됩니다. TypeError: Failed to execute 'createObjectURL' on 'URL': Overload resolution failed..
if 문 내에서 미리 볼 이미지를 가리키는 URL을 생성하여 상태가 업데이트되고 이미지 이름을 사용하여 alt 속성도 업데이트됩니다.

마지막으로 전체 구성 요소는 다음과 같습니다.

import React, { useState } from 'react';
import placeholder from '../images/placeholder.png';
import './style.css';

const ImgPrev = () => {
    const [{alt, src}, setImg] = useState({
        src: placeholder,
        alt: 'Upload an Image'
    });

    const handleImg = (e) => {
        if(e.target.files[0]) {
            setImg({
                src: URL.createObjectURL(e.target.files[0]),
                alt: e.target.files[0].name
            });    
        }   
    }

    return (
        <form encType="multipart/form-data">
            <h1 className="form__title">Image Preview in Reactjs</h1>
            <div className="form__img-input-container">
                <input 
                    type="file" 
                    accept=".png, .jpg, .jpeg" 
                    id="photo" 
                    className="visually-hidden"
                    onChange={handleImg}
                />
                <label htmlFor="photo" className="form-img__file-label">
                    <svg width="150" height="150" viewBox="0 0 24 24" fill="none" stroke="#56ceef" strokeWidth="1" strokeLinecap="round" strokeLinejoin="round">
                        <path d="M5.52 19c.64-2.2 1.84-3 3.22-3h6.52c1.38 0 2.58.8 3.22 3" />
                        <circle cx="12" cy="10" r="3" />
                        <circle cx="12" cy="12" r="10" />
                    </svg>
                </label>
                <img src={src} alt={alt} className="form-img__img-preview"/>
            </div>
        </form>
    );
}

export default ImgPrev;


그러면 브라우저에서 다음과 같이 표시됩니다.

좋은 웹페이지 즐겨찾기