안녕하세요

투두리스트 본문

카테고리 없음

투두리스트

sakuraop 2022. 10. 6. 16:26

https://code-reading.tistory.com/114

위 블로그의 To Do List를 구현할 수 있도록 공부하기로 했습니다.


1. input의 value를 onChange이벤트와 write State를 이용해 나타내기

title과 content를 담을 input을 만듭니다.

onChange 이벤트에서 e.target.value로 인풋의 입력창에 입력되는 값에 접근합니다.

 

            <input type="text" name="title" onChange={(e) => e.target.value })} />
            <input type="text" name="content" onChange={(e) =>  e.target.value })} />
 

이 value를 write State에 담아줄 것입니다.

 

    const [write, setWrite] = useState();
 

useState를 이용해 write State를 만들고,

 

            <input type="text" name="title" onChange={(e) => setWrite({ [e.target.name]: e.target.value })} />
 
 

onChange의 setWrite에 키와 값을 지닌 객체로 전달할 것입니다. 
key는 e.target.name인 title, value는 e.target.value인 입력값이 됩니다.

 

setWrite는 write에 담겨있는 내용을 통째로 바꾸기 때문에 스프레드 연산자를 이용해 저장되어 있는 데이터에 새로운  값을 추가하도록 합니다.

 

            <input type="text" name="title" onChange={(e) => setWrite({ ...write, [e.target.name]: e.target.value })} />
            <input type="text" name="content" onChange={(e) => setWrite({ ...write, [e.target.name]: e.target.value })} />
 

2. write 객체로 list State에 저장하기 + onChange 이벤트를 함수로 만들기

useState를 이용해 배열 list를 만들어줍니다. 

 

    const [list, setList] = useState([]);
 
 

버튼을 누르면 list에 값이 저장되도록 합니다. 여기서도 마찬가지로 입력되어 있는 정보를 남겨두기 위해 스프레드 연산자를 쓰고, 데이터를 추가하도록 합니다.

 

            <button onClick={() => setList([...list, write])}>작성하기</button>
 
 
 
onChange 기능을 가독성을 높이고 관리하기 쉽도록 함수로 만들어줍니다.

 
    const writeHandler = (e) => {
        setWrite({ ...write, [e.target.name]: e.target.value });
    };
            <input type="text" name="title" onChange={writeHandler} />
 

코드보기

더보기

import
React, { useRef, useState } from "react";

const App = () => {
    // const num = useRef(1);
    const [write, setWrite] = useState({});
    const [list, setList] = useState([]);

    const writeHandler = (e) => {
        setWrite({ ...write, [e.target.name]: e.target.value });
    };

    return (
        <div>
            {list.map((el, idx) => {
                return (
                    <div key={idx}>
                        <li>제목 : {el.title}</li>
                        <li>내용 : {el.content}</li>
                    </div>
                );
            })}

            <input type="text" name="title" onChange={writeHandler} />
            <input type="text" name="content" onChange={writeHandler} />
            <button onClick={() => setList([...list, write])}>작성하기</button>
        </div>
    );
};

export default App;

 
 
출력화면

3. 수정 및 삭제를 할 수 있도록 데이터의 객체 각각이 고유한 id를 가지도록 하기

useRef를 이용하여 변수를 생성합니다.

 

    const listNum = useRef(1);
 
 

id키를 추가하도록 합니다.

listNum의 값에 접근하려면 listNum.current에 접근하면 됩니다. 

 

    const writeHandler = (e) => {
        setWrite({ ...write, [e.target.name]: e.target.value, id: listNum.current });
    };
 

 

리스트가 생성될 때마다 listNum의 값을 1 더해줘서 각 리스트가 고유한 id를 가질 수 있도록 합니다.

 

    const listHandler = () => {
        setList([...list, write]);
        listNum.current++;
    };

 


4. list에 데이터를 저장하면 입력창 비우기 (제어 컴포넌트 방식으로)

작성 버튼을 누르고 나면 입력한 창을 비울 수 있도록 합니다.

setWrite로 title과 content를 초기화합니다.

 

    const listHandler = () => {
        setList([...list, write]);
        listNum.current++;

        setWrite({
            title: "",
            content: "",
        });
    };
 
 

input의 value 값을 write.title과 write.content로 설정합니다.

 

            <input type="text" name="title" onChange={writeHandler} value={write.title} />
            <input type="text" name="content" onChange={writeHandler} value={write.content} />
 


5. 아무 입력이 없을 경우에는 포커스하기

useRef를 이용합니다.

 

    const titleRef = useRef();
    const contentRef = useRef();
 
 

input에 ref를 전달합니다.

 

            <input type="text" name="title" onChange={writeHandler} value={write.title} ref={titleRef} />
            <input type="text" name="content" onChange={writeHandler} value={write.content} ref={contentRef} />
 

 

작성하기 버튼을 누르면 alert로 경고창을 띄웁니다.

 

    const listHandler = () => {
        if (write.title.length < 1) {
            alert("제목을 입력해주세요.");
            titleRef.current.focus();
            return;
        }
        if (write.content.length < 1) {
            alert("내용을 입력해주세요.");
            contentRef.current.focus();
            return;
        }

코드보기

더보기
import React, { useRef, useState } from "react";

 

const App = () => {
    const listNum = useRef(1);
    const titleRef = useRef();
    const contentRef = useRef();

 

    const [write, setWrite] = useState({
        title: "",
        content: "",
    });
    const [list, setList] = useState([]);

 

    const writeHandler = (e) => {
        setWrite({ ...write, [e.target.name]: e.target.value, id: listNum.current });
    };

 

    const listHandler = () => {
        if (write.title.length < 1) {
            alert("제목을 입력해주세요.");
            titleRef.current.focus();
            return;
        }
        if (write.content.length < 1) {
            alert("내용을 입력해주세요.");
            contentRef.current.focus();
            return;
        }

 

        setList([...list, write]);
        listNum.current++;

 

        setWrite({
            title: "",
            content: "",
        });
    };

 

    return (
        <div>
            {list.map((el, idx) => {
                return (
                    <div key={idx}>
                        <li>작성 번호 : {el.id}</li>
                        <li>제목 : {el.title}</li>
                        <li>내용 : {el.content}</li>
                    </div>
                );
            })}

 

            <input type="text" name="title" onChange={writeHandler} value={write.title} ref={titleRef} />
            <input type="text" name="content" onChange={writeHandler} value={write.content} ref={contentRef} />
            <button onClick={listHandler}>작성하기</button>
        </div>
    );
};

 

export default App;

 


 

6. 삭제하기 버튼을 만들어 id와 일치하는 목록 삭제하기

removeHandler 함수를 만듭니다.

filter함수를 이용해 매개변수로 입력받은 값이 리스트의 id와 일치하는 리스트를 제외하도록 합니다.

 

    const removeHandler = (listId) => {
        setList(list.filter((el) => el.id !== listId));
 
 
    };

삭제하기 버튼을 만들어 onClick이벤트에 removeHandler를 전달하고, 인자로는 el.id를 줍니다. 

 

            {list.map((el, idx) => {
                return (
                    <div key={idx}>
                        <ul>
                            <li>작성 번호 : {el.id}</li>
                            <li>제목 : {el.title}</li>
                            <li>내용 : {el.content}</li>
                        </ul>
                        <button onClick={() => removeHandler(el.id)}>삭제하기</button>
                    </div>
                );
            })}

2번 리스트의 삭제하기 버튼을 누르면

 

해당 요소가 filter된 결과가 나타납니다.


 

7. 컴포넌트화

작성 컴포넌트 EditDiary.js

리스트 컴포넌트 ListDiary.js

리스트 아이템 컴포넌트 ItemDiary.js

를 만들어 각각의 파일의 기능을 담습니다.

 

이 부분부터는 파일이 나뉘어 있어 코드 전체를 첨부하지 않겠습니다.

 

 

const App = () => {
    const [diaryList, setList] = useState([]);

    const removeHandler = (listId) => {
        setList(diaryList.filter((el) => el.id !== listId));
    };

    return (
        <div>
            <EditDiary diaryList={diaryList} setList={setList} />
            <ListDiary removeHandler={removeHandler} diaryList={diaryList} />
        </div>
    );
};

export default App;

 


 

8. 수정하기