#09 리액트 입문 : 1차로 만들었던 todolist 리팩토링

728x90
반응형

1. 처음으로 만들었던 투두리스트 [2023.11.06] 리팩토링 !

https://zerotonine2da.tistory.com/64

 

#08 리액트 입문 :: todolist 만들기 (리액트 컴포넌트 분리)

TIL 리액트로 투두리스트를 구현하면서, JSX문법 사용과 랜더링에 대해 배울 수 있었다. 리랜더링이 끝나는 시점에 대해 알 수 있었고, useState를 사용하여 리액트에게 변경값을 알려주는 개념을

zerotonine2da.tistory.com


2. 개선 내용

1. <form>태그의 onSubmit 사용

2. id값 = uuid 사용 

3. Working과 Done부분을 하나의 컴포넌트 로 만들기 --중복 줄이기

- 기존에는 Contents라는 컴포넌트 안에 (Working + Done부분을 2개의 DIV태그로 사용했음)

 


3. 반영 내용

1. App.jsx

import { useState } from 'react';
import './App.css';
import uuid from 'react-uuid';
import Inputs from './component/Inputs';
import Contents from './component/Contents';

function App() {
    const initialState = [
        { id: uuid(), title: '제목1', content: '내용1', isDone: false },
        { id: uuid(), title: '제목2', content: '내용2', isDone: false },
        { id: uuid(), title: '제목3', content: '내용3', isDone: true },
    ];
    const [todos, setTodo] = useState(initialState);

    return (
        <>
            <header></header>
            <main>
                <Inputs todos={todos} setTodo={setTodo} />
                <Contents todos={todos} setTodo={setTodo} isDone={false} />
                <Contents todos={todos} setTodo={setTodo} isDone={true} />
            </main>
            <footer></footer>
        </>
    );
}

export default App;

uuid() 란? 고유한 아이디를 생성할 수 있음

(1) 터미널 : npm install react-uuid / yarn add react-uuid 모듈 설치 

(2) import uuid from 'react-uuid'

(3) 원하는 구간에 uuid() 사용

 

Working과 Done부분을 하나의 컴포넌트 로 만들기 => Contents.jsx로 생성 

(isDone값으로 할일/완료일 구분)

 

2. Contents.jsx

import React from 'react';

function Contents({ todos, setTodo, isDone }) {
    return (
        <div>
            {isDone === true ? '완료목록' : '할일목록'}
            {todos
                .filter((item) => item.isDone === isDone)
                .map((todo) => {
                    return (
                        <div key={todo.id} style={{ background: '#538eed', margin: '10px' }}>
                            <div>{todo.title}</div>
                            <p>{todo.content}</p>
                            <button
                                onClick={() => {
                                    const deleted = todos.filter((item) => {
                                        return item.id !== todo.id;
                                    });
                                    setTodo(deleted);
                                }}
                            >
                                삭제
                            </button>
                            <button
                                onClick={() => {
                                    const stateChange = todos.map((item) => {
                                        return item.id === todo.id ? { ...item, isDone: !item.isDone } : item;
                                    });
                                    setTodo(stateChange);
                                }}
                            >
                                {isDone === true ? '취소' : '완료'}
                            </button>
                        </div>
                    );
                })}
        </div>
    );
}

export default Contents;

▶todos(할일들 리스트).filter( 'isDone:true /false)값에 따라 구분하기)

.map(각각의 할일을 생성)

▶삭제 버튼 : todos(할일들 리스트).filter(삭제버튼 누른 id와 할일(todo)랑 비교-> 안 같은 것들 출력)

+ setTodo로 랜더링

▶취소/완료 버튼 : todos(할일들 리스트).map(삭제버튼과 같이 id값 비교해서-> isDone값 업데이트)

+ {...item, isDone: !item.isDone} 으로 스프레드로 변경 (불변성을 위해)

+ setTodo로 랜더링

 

 

3. Inputs.jsx

import React from 'react';
import { useState } from 'react';
import uuid from 'react-uuid';

function Inputs({ todos, setTodo }) {
    const [title, setTitle] = useState('');
    const [content, setContent] = useState('');

    return (
        <div>
            <form
                onSubmit={(event) => {
                    event.preventDefault();
                    const newTodo = {
                        id: uuid(),
                        title,
                        content,
                        isDone: false,
                    };

                    setTodo([...todos, newTodo]);
                }}
            >
                제목
                <input
                    value={title}
                    onChange={(event) => {
                        setTitle(event.target.value);
                    }}
                ></input>
                내용
                <input
                    value={content}
                    onChange={(event) => {
                        setContent(event.target.value);
                    }}
                ></input>
                <button>입력하기</button>
            </form>
        </div>
    );
}

export default Inputs;

▶<form> 태그는 onSubmit 속성이 있음, 별 다른 설정이 없으면

<button>이  default로 작동됨. 

▶ 일반적신 속성으로 새로고침이 되서 -> event.preventDefault();

 

끝.

반응형