숙련과정이 계속 진행되고 오늘부터 일주일 뒤에 프로젝트가 시작이 된다.
숙련과정을 하려면 결국에 입문과정이 탄탄해야해서 오전 중으로는 항상 입문과정의 과제를 계속 만들어보고 있다.
그래서 오늘은 최종정리 겸 글을 쓰면서 전체적인 흐름을 상기시켜볼까한다. 내 머릿속으로 이해한 내용들을 다 적어보려고한다.
1.처음에는 코드 한 줄씩 마다 주석을 달면서 해석을 하는 시간을 가졌고
2. 그 다음은 한쪽은 완성본 한쪽은 빈페이지를 해놓고 내가 생각하는대로 적어보고 바로바로 확인을 하면서 진행을 하고
3.마지막으로는 완성본을 보지 않고 나 스스로 만들어보는 과정을 하고 있다.
내일부터 redux로 투두리스트를 만들어보려고하기 때문에 오늘까지 리액트로 투두를 만들어보자는 생각에
3번째 과정을 실행했다.
처음에 <Header>{children}<Header> 이렇게 children을 가져와서 헤더부분의 컴포넌트와 연결하는 것은 물 흐르듯이 하고🌝
두 번째로 메인으로 인풋의 구역을 나눠주고 input은 따로 컴포넌트를 만들었다.
<main style={{ padding: "20px", backgroundColor: "aliceblue" }}>
<Input setTodos={setTodos} />
</main>
▼ Input컴포넌트에 있어야할 꺼
1)input _title
2)input_contents
3)button_추가버튼
일단 title에는 사용자가 인풋에 적은 값이 렌더링이 되어야하므로 onChange메소드를 써서 변화가 생길때마다 handleChange함수를
실행되도록 한다.
여기서 까먹지말고 이렇게 변화된 값을 알려주기 위해서 state에 값을 넣어줘야한다.
const [title,setTitle]=useState("") >>>>훅 임포트 필수!
이제 title이 바뀌므로 setTitle(event.target.value)를 실행해서 콘솔을 찍어보면 쓴 글자마다 콘솔에 찍힌다면 성공!
✨ 여기서 이벤트? change된다면 그 이벤트가 일어나는 target(=input)의 value(입력값)을 setState에 넣어준다는거
contents도 내용이 동일하므로 state=> contents ,setContents로 해주고 똑같이 해준다.
그럼 이제 추가버튼 실행을 해야한다.
여기서 이번에 새로 알게된 정보인데 <form>태그안에 버튼이 있다면 그 버튼을 누를경우 onSubmit이 실행되고 그에 할당한 함수를 실행한다. 그래서 form태그에 onSubmit={handleSubmit}을 입력한다.
const handleSubmit =(e)=>{
e.preventDefault();
const newTodo={title,contents,isDone:false , id:uuidv4()
setTodos((prev)=>{return[...prev,newTodo]})
}
}
여기서 실행된 이벤트는 submit이 되면 자동으로 새로고침되므로 새로고침을 방지해준다.
그리고 newTodo라는 todos의 객체모양을 가지지만 새로입력한 내용을 가진 newTodo를 만들어준다.
여기서 title:title은 =>title 이렇게 하나로 줄여서 쓸 수 있다. 아주 유용! 코드가 좀더 간편해서 보기 좋은거 같다.
그리고 이제 setTodos가 가지고 있던 전의 값(=prev)를 스프레드문법으로 나열하고 거기에 newTodo를 넣어준다.
그럼 투두리스트 추가를 할 준비가 끝이다.
사실 여기까지하고 헷갈렸던부분이 이렇게 하면 투두가 리스트구역에 올라와야하는거 아닌가?
이런 생각을 했는데 가만보니 올라 갈 카드들과 구역들을 만들어놓지 않았고 내가 지금까지 만든것은 유저가 작성한 글을 가지고
화면에 렌더링이 될 수 있도록까지를 만든 과정이다.
헷갈리지말자!ㅋㅋ(나중에 다른 프로젝트하면 또 이런 비슷한 문제로 헷갈릴꺼같으니까 미리 알아채자)
그럼 인풋이 끝나면 다시 App.js로 돌아와서
<TodoList todo={todos} isActive={true} setTodos={setTodos} />
<TodoList todo={todos} isActive={false} setTodos={setTodos} />
인풋밑에 투두들이 들어갈 공간을 만들어준다 근데 왜 두 개냐면??!
위에는 Working 즉 지금 하고 있는 일이고 , 밑에는 Done구역이다 Working구역에서 완료버튼을 누르면 Done구역으로 넘어오는 구조
라서 두 개로 나누어 주었다.
그래서 구분을 isActive로 했다 true= Working지금 하는 중이다. false = Done 끝난일이다.
그리고 이 구역에 새로운 투두들이 들어와야하므로 props들로 내려주었다.
TodoList({todo,isActive,setTodos})
이렇게 props 받았다.
그럼 이제 <h2>{isActive?Working🔥:Done⚡️}</h2>정해준다..
이 부분보고 와 되게 기발하다라고 생각했다... 이 한문장으로 두가지 구역을 다 나눴네라는 생각이 들었다...
이제 구역 제목 가지고 고민 할 시간은 줄였다!!!
그리고 TodoList는 기존에 가지고 있었던 todos들에 새로운 todos를 구역에 따라 올라갈 수 있도록 만든다.
<h3>밑에다가 내려받은 props를 받는다.
!!자바스크립트를 써야하므로 중괄호 안에다가 써준다
{todo.filter((item)=>item.isDone=== !isActive).map((item)=>{return <Todo/>})}
일단 filter를 써서 이 todo안에있는 것들을 item으로 정해주고 이 아이템틀중에서 isDone과 isActive가 반대인것만 filter에 걸러라.
즉 이 말은 isDone의 false(=Working) , isActive의 true(=Working)이므로 이 두 개가 같은 친구들을 Working으로 보내라 라는 뜻
그리고 그 중에서 또 map을 사용해서 이 해당하는 아이템을 새로운 배열로 하나씩 반환해서 Todo컴포넌트로 반환한다.
사실 지금 이부분 적으면서 썼다지웠다 너무 많이하고 있는데 이해가 완벽하지 않은것 같으므로 내일 추가공부당첨
그리고 마지막 컴포넌트인 Todo에 가면
이제 이 컴포넌트는 투두카드 하나하나씩을 나타낸다.
이제까지 전체 틀을(App.js)->헤더 + 사용자 입력창 + 리스트구역까지 했으므로 ->리스트에 들어갈 하나 하나를 나타내는 Todo이다.
그 전에 이제 이 카드들을 만들려면 투두리스트에서 item들을 거르고 걸러서 새로받은 props들을 받아야한다.
function Todo({ item, setTodos, isActive })
item은 todoList의 item, setTodos는 이제 todo를 바꿔야하므로 , isActive는 취소와 완료버튼에 의해서 바뀔 기능을 위해서 가져왔다.
리턴 할 모습은
<h5> {item.title}</h5>
<p>{item.contents}</p>
<button>완료 || 취소</button>
<button>삭제</button>
todo로부터 거르고 걸러서 온 Item들의 title,contents를 투두카드에 넣어주고
이제 버튼구현이 문제다.
여기서 엄청 해맸다..ㅠㅠㅠㅠㅠㅠ
먼저 그나마 쉬운 삭제부터하자면, <button onClick={handleDelete}>입력
const handleDelete=()=>{
setTodos{(prev)=>prev.filter((t)=>t.id !== item.id)}
}
헷갈렸던 부분은 t와 item은 같지않나?라는 생각이였다.
근데 prev는 지금 기존에 있던 todo를 얘기하고 그 모든 todo를 하나씩 가지고 있는 것을 t라고 한다.
item은 지금 내가 삭제한 이 버튼! 을 말하는것같다.
그럼 필터를 통해서 내가 누른 이 item의 id가 전체를 가지고 있는 t중에서 같은 id를 가진 todo만 빼고 나와라 라고 해석이 된다.
삭제구현은 간단하게 끝
그리고 이제 버튼을 누르면 구역을 왔다리갔다리하는것만 남았다.
멀리 달려왔다 ㅠ
<button onClick={handleChange}>
const handleChange=()=>{
setTodos(prev=>prev.map((t)=>{
if(t.id===item.id){return {...t,isDone: !t.isDone}}
} else{return t;}
});
);
};
와 이게 방금 적으면서 쫌 더 이해가 간거같다.
setTodos(prev=>prev.map((t)=>{
if(t.id===item.id){return {...t,isDone: !t.isDone}}
이 부분은 일단 앞에서 본것처럼 전에 전의 todo를 t로 하나씩 가지고 있고 이 t의 id와 내가 완료버튼을 누른 item의 id가 같다면!
기존의 t에 isDone부분을 바꿔라가 된다.
스프레드 문법을 이용하면 이렇게 부분적인 것을 바꿀 수 있다.
그럼 isDone을 바꿨는데 어떻게 Working or Done으로 어떻게 가는것인가?
아까 앞에서 {todo.filter((item)=>item.isDone=== !isActive).map((item)=>{return <Todo/>})} 이부분에 의해서
isActive와 isDone이 반대로 되면서 기존에 있던 Working에서 Done으로 바뀌는것을 알 수 있다.
여기까지 투두리스트를 만드는 과정이다.
거의 다 안다고 생각했는데 다시 글을 적으면서 실행하니까 애매모호한 부분이 많네.....
이 부분은 내일 다시 확실히 공부해야겠다.
그리고 오늘 이렇게 다 적어놓고 오류가 계속 떠서 고생했었는데
App.js에서 todoList컴포넌트에 todo={todos}라고 적어놨었는데 무의식으로 todoList부터 todos를 props으로 쓰다보니
자꾸 못찾겠다는 오류가 떠서 답답했었는데 이런 사소한 이유였다 ㅠ prop를 넘겨줄떄는 무심코 넘기지 말자는 교훈을 받으면서
오늘 이렇게 기나긴 TIL을 종료하려고 한다.
끝😎
'TIL✨' 카테고리의 다른 글
불변성_TIL(36) (0) | 2022.12.19 |
---|---|
아침부터 오류 만남 ㅎ TIL(34) (0) | 2022.12.15 |
redux로 카운터를 만들어 보자_TIL(32) (0) | 2022.12.13 |
Redux_TIL(30) (0) | 2022.12.09 |
Redux_TIL(29) (0) | 2022.12.09 |