728x90

Dropzone이란 라이브러리가 존재하고, 이를 React hook방식으로 사용하도록 만든 것이 react-dropzone이다.

설치

npm install --save react-dropzone
yarn add react-dropzone
### 목적
프리뷰가 있고, Drop한 이미지를 삭제할 수 있어야한다.

먼저 react-dropzone의 Preview 코드를 가져온다.

import React, {useEffect, useState} from 'react';
import {useDropzone} from 'react-dropzone';

const thumbsContainer = {
  display: 'flex',
  flexDirection: 'row',
  flexWrap: 'wrap',
  marginTop: 16
};

const thumb = {
  display: 'inline-flex',
  borderRadius: 2,
  border: '1px solid #eaeaea',
  marginBottom: 8,
  marginRight: 8,
  width: 100,
  height: 100,
  padding: 4,
  boxSizing: 'border-box'
};

const thumbInner = {
  display: 'flex',
  minWidth: 0,
  overflow: 'hidden'
};

const img = {
  display: 'block',
  width: 'auto',
  height: '100%'
};


function Previews(props) {
  const [files, setFiles] = useState([]);
  const {getRootProps, getInputProps} = useDropzone({
    accept: {
      'image/*': []
    },
    onDrop: acceptedFiles => {
      setFiles(acceptedFiles.map(file => Object.assign(file, {
        preview: URL.createObjectURL(file)
      })));
    }
  });
  
  const thumbs = files.map(file => (
    <div style={thumb} key={file.name}>
      <div style={thumbInner}>
        <img
          src={file.preview}
          style={img}
          // Revoke data uri after image is loaded
          onLoad={() => { URL.revokeObjectURL(file.preview) }}
        />
      </div>
    </div>
  ));

  useEffect(() => {
    // Make sure to revoke the data uris to avoid memory leaks, will run on unmount
    return () => files.forEach(file => URL.revokeObjectURL(file.preview));
  }, []);

  return (
    <section className="container">
      <div {...getRootProps({className: 'dropzone'})}>
        <input {...getInputProps()} />
        <p>Drag 'n' drop some files here, or click to select files</p>
      </div>
      <aside style={thumbsContainer}>
        {thumbs}
      </aside>
    </section>
  );
}

<Previews />

하나의 파일만 받아오려면 옵션을 넣어야 한다.

const {
        getRootProps,
        getInputProps,
        isFocused,
        isDragAccept,
        isDragReject,
    } = useDropzone({
        onDrop: acceptedFiles => {
            setFiles(acceptedFiles.map(file => Object.assign(file, {
                preview: URL.createObjectURL(file)
            })))
        }, accept: { 'image/*': [], multiple: false }
    });

mutiple: false란 옵션을 이용하면 된다.

### 올린 파일 삭제

제일 어려웠던 부분은 올린 파일을 삭제하는 방법이었다.

파일을 어떻게 삭제할까?

<aside style={thumbsContainer} onClick={() => setFiles([])} >
                    {files.map(file => (
                        <div>
                            <div style={thumb} key={file.name}>
                            <div style={thumbInner}>
                                <img
                                    src={file.preview}
                                    style={img}
                                    // Revoke data uri after image is loaded
                                    onLoad={() => { URL.revokeObjectURL(file.preview) }}
                                    alt="preview"
                                />
                            </div>
                        </div>
                            <div>{file.path}</div>
                        </div>
                    ))
              }
</aside>

파일의 내용을 보여주는 코드에 onClick을 달아 state를 초기화하는 방법이다.

또는 여러개의 파일을 사용한다면, setFiles( files.filter( f => ) )방법으로 하면 된다.

반응형
728x90

왜 우리는 상태 관리를 할까?


아무런 이유 없이 나는 강의에서 사용해서 사용했다 😥


 저는 초반 웹 개발을 배우면서 Vuex(상태 관리 라이브러리)를 사용하니까 사용했습니다. 그래서 상태 관리 라이브러리가 무엇인지 제대로 고민해보지 못한 것 같습니다. 개발을 점점 진행하다 보니 상태 관리가 무엇인지 서버에서 가져온 값은 무엇인지 고민하게 되어 이 글을 작성합니다.

상태 관리란?

상태 관리를 한국어로 할 때 더 직감적으로 이해하는 데 있어 방해가 된다고 생각합니다. 영어로 적을 시 State Management입니다. 여기서 State를 볼 수 있는데 State는 리액트의 useState 훅에서 가리키는 State를 말합니다. 한마디로 페이지나 컴포넌트에서 사용되는 State를 관리하는 라이브러리입니다.

왜 상태를 관리해야 할까?

 리액트나 뷰나 하나의 페이지를 컴포넌트 단위로 나누어 만들고 있습니다. 상위 컴포넌트에서 하위 컴포넌트로 데이터를 넘겨줍니다. 또 한번 더 컴포넌트에서 컴포넌트로 데이터를 넘겨주는 경우도 존재합니다. 그렇기에 점점 컴포넌트 깊이가 길어지면 상태를 관리하는 데 있어 불편함이 존재합니다. 아래 영상을 보면 쉽게 이해할 수 있습니다.

 예를 들어 매번 props로 데이터를 넘겨줘야한다거나, 상위 컴포넌트에서 어떤 값을 넘겨주었는지 기억을 해야한다거나, 원하는 데이터가 형제 컴포넌트에 있어서 상위 컴포넌트에서 값을 두개로 넘겨줘야한다거나 등의 불편을 느낄 수 있습니다. 그래서 나온 것이 리덕스입니다.

https://miro.medium.com/max/700/1*Rwq-0CxITh6DCwW8J9p9pw.gif

왜 리덕스?

 Recoil, Vuex, Ngrx 등 모두 리덕스 개념에서 시작되었으며, 리덕스는 리액트에만 사용하라고 만든 라이브러리가 아닙니다. 위 Gif와 같이 Store란 친구로 Props 대신해 데이터를 뿌려줍니다. 실제 사용하면 Store가 프론트의 DB처럼 느껴집니다.

클라이언트? 서버? 상태 관리?

 우아한형제들에서 발표한 React-Query 소개 영상을 통해 서버 상태 관리 단어를 처음 봤습니다. 그리고 리덕스와 비슷한 라이브러리들이 클라이언트 상태 관리란 것도 처음 들었습니다. 클라이언트 상태 관리? 서버 상태 관리? 이게 무슨 차이일까요?

서버 상태 관리 라이브러리 React-query/Swr

 SWR 라이브러리를 사용해보지 못해 모르지만 react-query는 사용해봐 알고 있습니다. 주식을 생각해보면 주식의 데이터는 값이 계속 변동이 되어야 합니다. 바로 돈과 직결되는 문제가 발생하기 때문입니다. 그렇기에 이 데이터를 서버의 데이터베이스의 상태와 동일하게 유지되어 좋습니다. 그렇기에 주기적으로 서버 데이터를 프론트로 가져와야합니다. 이 과정의 코드 구현을 해소해주는 라이브러리가 서버 상태 관리입니다.

클라이언트 상태 관리 라이브러리란?

 그럼 클라이언트 상태 관리 라이브러리는 무엇일까요? 기존 리덕스를 사용하는 프로젝트들을 보면 action에 axios를 사용하여 값을 업데이트했습니다. 이런 식으로 화면에 보여주는 값들을 action을 통해 가져와 관리하는 라이브러리입니다

왜? 서버 상태 관리 라이브러리가 존재해?

 서버에서 가져온 데이터는 서버에 있는 데이터와 동일할까요? 그럴 수도 있고 아닐 수도 있습니다. 그렇기때문에 주기적으로 데이터를 가져와 서버 상태와 동일하게 유지해야합니다. 그런데 리덕스에서는 이렇게 주기적으로 호출하여 가져오려면 따로 코드를 작성해야합니다. 그렇기 때문에 이를 편리하게 해주는 라이브러리가 나왔습니다.

 우리는 서버에서 가져온 값을 Props로 많이 넘기고 있기 때문에  UI에 사용되는 State보다 서버에서 가져온 State를 많이 사용하고 있다고 생각합니다.

혼용해도 될까? 하나만 써야할까?

 처음에는 리액트 쿼리와 리덕스를 같이 사용하려고 했습니다. 하지만 생각해보니 동일한 데이터를 같이 캐시에 담아두면 메모리 낭비가 발생한다고 생각했습니다. 리액트 쿼리를 사용하는 게 서버에서 값을 가져와 관리하기 편하다고 느낍니다. 그래서 리액트쿼리를 사용하고, 클라이언트 간에 UI State 관리가 힘들어진다면 그때 리덕스를 사용할 예정입니다.(사실 리덕스보다 Zustand를 사용할 생각입니다.)

참고


이미지 참조: How to Pass Data between React Class Components

반응형

'코딩 관련 > 자바스크립트' 카테고리의 다른 글

페이지 재로딩 시 상단 이동  (0) 2023.10.19
Console.log 그렇게 쓰지 마요..  (0) 2023.10.19
React-Dropzone 모듈 만들기  (0) 2022.07.08
군 계산기 만들기  (0) 2018.09.26
Moment js 너란 넘은 정말..  (0) 2018.09.26
728x90

TStory에 군 계산기 만들기 Ver.1

환경
Tstory 게시글( HTML모드)
사용한 언어
JavaScript
사용한 라이브러리
Moment.js
참고한 사이트
W3Schools
  1. Moment.js에서 사용할 라이브러리를 다운받아옵니다.
  2. 티스토리 스킨 편집에서 업로드해줍니다.

업로드 하는 방법

html편집보기
html편집에 들어가서
업로드
파일 업로드에 다운받은 Moment.js를 올려줍니다

그리고 글 쓰기에 html버튼을 눌러줍니다

Ver.1로 만들고 싶었던 제 군 생활 퍼센트는
그저 단순히 제 군생활 퍼센트만 보여주기만 하면 됩니다.
그 다음 추후 수정할 것에는 남은 일수 + 다른 사람 군생활 계산
<style>
#myProgress {
  width: 100%;
  background-color: #ddd;
}

#myBar {
  width: 10%;
  height: 30px;
  background-color: #4CAF50;
  text-align: center;
  line-height: 30px;
  color: white;
}
</style>
<div id="myProgress">
  <div id="myBar"></div>
</div>


<script src="moment.js"></script>
<script>

var now = moment(); // Moment에서 오늘 날짜를 받습니다.
var endDate = moment("2019-10-31T23:35:01");   //자신의 전역일
var resultDate = endDate.diff(now, 'days', true);//차이 구하기`enter code here`
resultDate = Math.floor(resultDate);

var workedDays = 667-resultDate;//지금까지한 복무일수

var result = workedDays/667; // 현재 남은 퍼센트
result = result*100; // 소수점으로 나오닌 100을 곱해주고
result = result.toFixed(2); // toFixed함수로 소수점을 버려준다

var elem = document.getElementById("myBar"); // document의 progress Bar를 지정해준다. elem 변수에 
var width = result; // Progress Bar 채울 내 복무 너비
elem.style.width = width + '%';  // 지정해주기
elem.innerHTML = width * 1  + '%'; // Bar 안에 보여줄 글씨

</script>
반응형
728x90

군계산기를 만들어보고 싶었다고...


RubyOnRails를 배우고 어언 1년 ... 헛것을 배웠나 ... 여전히 못한다 힛..

HTML이니 CSS니 못한다. .. JS 못한다. ㅇㅂㅇ.. ? ?

겉햝기 식으로만 할줄 아니 이걸 어찌 하려나

그냥 다시 배워야지 이것 밖에 답이 없는 것 같기도 하고... 흐아...;;;


지금은 오랜만에 티스토리를 다시 하는 만큼 새로운 걸 해보고 싶었고, 구글 블로그(blooger)에서 자바스크립트가 돌아가길래

티스토리도 되나 싶었는데 된다.

이 글을 읽고 싶도 해보고 싶다면 따라 해봐라

글 쓰기 버튼을 누르고 사진 슬라이드쇼 동영상 파일 버튼 맨 오른쪽에 HTML 체크 박스가 있다 눌러서 그 안에다

 <script type="/text/javascript> alert("HI JS"); </script>

하면 메세지창이 하나 등장할 것이다.


군계산기를 만들기 위해서 필요한 것들은 정말 별 것 없다.

현재 날짜와 내 제대 날짜 이 두개와 이쁘게 표시할 div박스와 css 조금

이걸 위젯으로 만들어서 해둘 수도 있겠다.


일단 Moment js가 이 티스토리에서 돌아가냐 였는데

돌아간다. 그냥 상상하는게 다 된다고 생각하면 될 것 같다.

문제는 Momentjs를 아직 잘 못 다룬다는 것이다.

var end(전역일)란 변수에 moment("2019-10-31", "YYYY-MM-DD").format("YYYY-MM-DD")라고 초기화하면

2019-10-31 딱 원하는 값을 얻게 된다.

이와 같이 현재 날짜도 2018-??-??식으로 값을 받으면 되고

그리고 이 둘 사이의 몇 일 남았는지 계산하고 그리고 이를 D-Day 형식이라던가

progress Bar 형식으로 표현하면 끝이다. 그리고 퍼센트도 계산해주면 좋지

더 나아가 모든 군인들... 남은 시간을 세고 있으니 내 껏뿐만 아니라

(이미 군단축 날짜를 뺀 )전역 날짜를 받아서 다른 사람의 군 생활 날짜도 구해줄 수도 있다.

간단한데 현재 두 날짜 사이의 몇일인지를 구하지 못하고 있다. Momentjs로 가능할 것 같은데 ;;

물론 그냥 현재 날짜랑 앞으로의 날짜를 아니 내가 직접 구해도 되긴 하는데 귀차.. 라이브러리를 사용했으면 끝까지 사용해보고 싶어서

어찌한ㄷㅁ...


반응형

+ Recent posts