Todo List

input에 할 일을 입력해 할 일을 추가하고, 완료한 것을 표시하고 수정도 가능 하도록 만들어 보자. 완료한 것이거나 해야할 것을 삭제하는 컨트롤도 구현해보자. filter 기능을 사용해서 모두 보거나 해야 할일 혹은 완료된 것을 볼 수 있도록 해보자. 그리고 Router를 구현해서 filter 마다 URL을 다르게 표현해보자. 그리고 todoList의 데이터들을 localStorage에 저장해보자.

개발 환경 설정(Rollup)

npm i -D rollup

Main UI 구현

function App() {
  return (
    <div className="App">
      <div className='container'>
        <div className='initial-box'>
          <div className='text-center'>
            이미지가 없습니다.<br/>
            이미지를 추가해주세요.          
          </div>
          <div className='plus-box'>
            +
          </div>
        </div>
      </div>
    </div>
  );
}
.text-center {
  text-align: center;
}

.plus-box {
  width: 100px;
  height: 100px;
  border: solid 1px #707070;
  font-size: 24px;
  display: flex;
  justify-content: center;
  align-items: center;
  line-height: 24px;
}

.initial-box {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  gap: 80px;
}

.container {
  width: 100vw;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
}

이미지 갤러리 구현

function ImageBox(props: {
    src: string
}) {
    return <div className="image-box">
        <img src={props.src} />
    </div>
}

export default ImageBox;
const inpRef = useRef<HTMLInputElement>(null);

    <input type='file' ref={inpRef} />
    <div className='plus-box' onClick={() => {
    inpRef.current?.click()
    }}>
    +
    </div>

Conversion from local image URL to Data URL

    <input type='file' ref={inpRef} onChange={(event) => {
        const file = event.currentTarget.files?.[0];
        if (file) {
            const reader = new FileReader();
            reader.readAsDataURL(file);
            reader.onloadend = (event) => {
            setImageList(prev => [...prev, event.target?.result as string]);
            };
        }
    }} />
    {
        imageList.map((path, index) => <ImageBox key={path + index} src={path}/>)
    }
    <div className='plus-box' onClick={() => {
        inpRef.current?.click()
    }}>
    +
    </div>

완성본 보러가기

끝!