개발/React (페이지 제작과정)

이미지 업로드 페이지를 만들어보자.

후엥_ 2023. 8. 23. 05:53
728x90
반응형

hover 를 이용한 마우스를 가져댈경우 우측 색으로 변한다.

일단 이미지 업로드만 할 수 있는 게시판을 만들고 싶었다. 그래서 서버와 관련된 코드를 빼고 어떻게 JS와 Css를 작성했는지 한번 기록 겸 남겨두려고 한다.  필요한 건 간단하다. 맨 위 제목을 작성하고 이미지들을 업로드 드래그 앤 드롭으로 끌어 넣으면 계속 추가되는 형식의 사이트이다.

 

 

 

export default function ImageUploadForm() {
  const [selectedFiles, setSelectedFiles] = useState([]);
  const fileInputRef = useRef(null);

  const handleFileChange = (event) => {
    const files = Array.from(event.target.files);
    setSelectedFiles((prevFiles) => [...prevFiles, ...files]);
  };

  const handleDrop = (event) => {
    event.preventDefault();
    const files = Array.from(event.dataTransfer.files);
    setSelectedFiles((prevFiles) => [...prevFiles, ...files]);
  };

  const handleUploadTextClick = () => {
    fileInputRef.current.click();
  };

  return (
    <div>
      <Navbar page="이미지 업로드 Form" />
      <Container>
        <section id="ex9">
          <h1>사진</h1>
          <TitleInput>
            <label>제목</label> <input type="text" />
          </TitleInput>
          <ImageInput>
            <div
              className="upload-box"
              onDrop={handleDrop}
              onClick={handleUploadTextClick}
              onDragOver={(e) => e.preventDefault()}
            >
              <Inputt>
                <input
                  ref={fileInputRef}
                  className="btn-file d-none"
                  type="file"
                  onChange={handleFileChange}
                  multiple
                />
                {selectedFiles.length > 0 ? (
                  <div>
                    <div className="viewer">
                      {selectedFiles.map((file, index) => (
                        <div key={index} className="file-preview">
                          <Image
                            src={URL.createObjectURL(file)}
                            alt={`미리보기 ${index + 1}`}
                            width={100}
                            height={100}
                          />
                        </div>
                      ))}
                    </div>
                  </div>
                ) : (
                  <div className="noneimg">
                    <img src="/cloude.png" alt="클라우드 이미지" />
                    <p>사진을 끌어서 넣거나 클릭해주세요</p>
                  </div>
                )}
              </Inputt>
            </div>
          </ImageInput>
          <button className="btn btn-primary">등록</button>
        </section>
      </Container>
    </div>
  );
  }

일단은 위에 코드가 전문이다.  코드를 하나하나 뜯어서 어떻게 제작이 된건지에 대해 말해보려고 한다. 

 

  const [selectedFiles, setSelectedFiles] = useState([]);
  const fileInputRef = useRef(null);

여기서 useState를 사용하여 selectedFiles라는 상태 변수와 setSelectedFiles라는 상태 업데이트 함수를 생성한다. 이 변수는 업로드할 이미지 파일을 추적할 예정이다. useRef를 사용하여 fileInputRef라는 ref를 생성할 예정이다. 이 ref는 파일 입력(input) 엘리먼트를 참조하는 데 사용된다. 

 

여기서 Ref 가 뭔지 모를 수 있는데 Ref는 ref는 React에서 사용되는 참조(reference)를 나타내는 개념이다. React 컴포넌트 안에서 DOM 요소나 다른 React 요소를 참조하고 조작할 때 사용된다.

 

 const handleFileChange = (event) => {
    const files = Array.from(event.target.files);
    setSelectedFiles((prevFiles) => [...prevFiles, ...files]);
  };

handleFileChange 함수는 파일 입력(input) 엘리먼트에서 파일을 선택했을 때 호출된다. 선택한 파일들을 배열로 변환하고, 기존에 선택한 파일 목록(selectedFiles)에 새로운 파일들을 추가한다.

 

 

const handleDrop = (event) => {
    event.preventDefault();
    const files = Array.from(event.dataTransfer.files);
    setSelectedFiles((prevFiles) => [...prevFiles, ...files]);
  };

handleDrop 함수는 파일을 드래그 앤 드롭하여 업로드할 때 호출된다. 이 함수는 드롭 이벤트를 처리하고 드롭한 파일들을 배열로 변환한 다음 기존 선택한 파일 목록에 추가한다.

 

  const handleUploadTextClick = () => {
    fileInputRef.current.click();
  };

handleUploadTextClick 함수는 Div 박스를 클릭했을 때 파일 입력(input) 엘리먼트를 클릭하도록 한. 이렇게 하면 사용자가 파일 선택 대화 상자를 열 수 있다.

 

 

 

넣는 방식에 따라 아래와 같이 흘러간다.

드래그 해서 넣으면 -> handleDrop 호출 -> handleFileChange-> 이미지를 배열로 저장

div를 선택해서 넣으면 -> handleUploadTextClick ->  handleFileChange -> 이미지를 배열로 저장

 

여기에 CSS랑 JSX를 적절하게 섞어서 코드를 작성한 것이다.

Flex를 활용해서 만약 이미지를 넣으면 미리 보기로 보이게 해 두었고 좌우 넓게 따라 자동으로 정렬되게끔 CSS를 짜두었다. 

 

생각보다 제작하면서 좀 많이 헤매었다. 드래그 앤 드롭으로 파일 넣는 걸 만들어보는 건 처음이기도 했고 파일을 배열로 만들어서 저장할 생각도 못해봤었기 때문에 조금 애를 먹었던 것 같다. 

 

css 코드가 궁금하면 댓글 달아두면 담에 Css코드도 좀 알려줘 보겠다 

728x90
반응형