https://velog.io/@bi-sz/투두리스트[2]
투두UI를 마무리했으니 기능을 추가해주도록 하겠습니다.
시작하기 전에 캘린더가 너무 위에 그려지는 느낌이라 paddingTop
에 30을 +
해주었습니다.
훨씬 자연스럽네요!
Calendar.js hook
에서 toggleTodo 함수를 만들어 두었으니 가져와줍니다.
rederItem에서 기존에 View
를 Pressable
로 변경해주었습니다.
터치했을 때 동작하는 onPress 에서는 toggleTodo함수가 실행되어 todo.isSuccess
를 토글시켜주는 동작을 합니다.
잘 동작하네요! 터치할 때마다 체크여부가 변경됩니다.
삭제하는 로직은 여러가지 방법이 있습니다.
체크하는 로직처럼 X 버튼을 추가하여 삭제를 해 주어도 되지만,
예의상 정말 삭제할 것인지 여부를 물어보도록하겠습니다.
onLongPress 함수가 실행되면 Alert
창을 띄워서 한 번 더 체크하겠습니다.
우선 Calendar.js hook
에서 작성해둔 removeTodo 를 가져와줍니다.
Alert
창의 버튼에서 어떤 동작이 있을건지 배열을 넘겨주었습니다.
style이 cancel
인 경우 누르는 순간 자동으로 모달이 닫힙니다.
그게 아닐 경우 어떤 동작을 할지 직접 적어주면 됩니다.
Todo를 길게 꾹 누르면 삭제할 것인지를 묻는 Alert
창이 뜹니다.
네
를 누르면 삭제되고, 아니요
를 누르면 창이 닫힙니다.
마찬가지로 Calendar.js hook
에서 작성해둔 addTodo 를 가져와줍니다.
간단하게 addTodo() 함수만 실행해줍니다.
추가가 잘 되는 모습입니다.
하지만 불편합니다..
입력이 완료되면 input의 내용을 지우고, +
버튼이 아닌 키보드의 전송?!
버튼을 눌러도 추가되도록 수정해주겠습니다.
AddTodoInput.js 파일의 TextInput
부분을 수정해줍니다.
수정이 끝났을 때 실행되는 함수인 onSubmitEditing 를 추가해주었습니다.
App.js의 AddTodoInput
부분에 onSubmitEditing을 추가해줍니다.
onSubmitEditind 이 실행될 때에도 addTodo()
되도록 해줍니다.
이제 +
버튼이 아닌 키보드의 체크 부분을 클릭해도 Todo가 추가됩니다.
use-todo-list.js 파일에서 resetInput
함수를 추가해주고 return
해주었습니다.
App.js 에서 받아줍니다.
Todo를 추가하는 로직에 추가해주었습니다.
Todo 추가 후에 Input창이 비워지는 모습입니다!
입력후에 키보드가 내려가는 현상을 블러가된다고 합니다.
저는 나쁘지 않다고 보는데 일단은 내려가지 않도록 수정해주었습니다.
AddTodoInput.js 파일의 TextInput
에서 blurOnSubmit을 false
로 변경해주었습니다.
키보드가 내려가지 않는 모습입니다.
바로 위 영상에서도 잘 보이듯이 Todo를 추가했을때 스크롤이 자동으로 마지막으로 내려오면 편리할 것 같습니다.
텍스트가 포커스가 되는 순간에 플랫리스트의 스크롤을 가장 아래로 해줍니다.
AddTodoInput.js 에 onFocus
를 추가해주었습니다.
react
의 useRef를 사용해줍니다.
함수를 작성해주었습니다.
원활한 동작이 되지 않아 스타일을 조금 변경했는데도 작동이 잘 되지 않습니다.
뭔가 될듯 말듯 한게... 열받습니다 ㅎㅎ
RN 자체의 문제라고 하니 우선 넘어가겠습니다.
use-todo-list.js 파일에서 todoList
대신 filteredTodoList
를 return 해줍니다.
App.js 에서도 todoList
대신 filteredTodoList
로 받아줍니다.
사진은 따로 찍지 않았지만 아래 코드에서도 todoList
를 받는 부분은 filteredTodoList
로 수정해주었습니다.
날짜별로 Todo가 적용되고 선택된 날짜의 Todo만 불러오는 것을 확인할 수 있습니다.
따로 이미지를 찍지 않았지만 기존에 넣어둔 default 데이터는 삭제해주었습니다.
직접 눌러보지 않고는 Todo가 추가된 날짜를 알 수 없어 Todo가 있는 날짜를 표시해주도록 하겠습니다.
캘린더를 그려주는 Calendar.js의 Column
에 Todo를 갖고있는지 여부를 알고있을 hasTodo를 추가해주었고, hasTodo 여부에 따라 Text
를 bold, normal처리 해주었습니다.
이미지는 따로 준비하지 않았습니다.
filteredTodoList로 변경하면서 지웠던 todoList도 다시 return
해서 사용할 수 있도록 수정해주었습니다.
Calendar.js 의 renderItem
부분에서 hasTodo의 값을 포함하여 넘겨줍니다.
Todo가 추가된 날짜의 Text
가 blod 처리된 것을 확인할 수 있습니다.
랜더링이 될 때마다 Todo가 초기값으로 세팅되어 저장한 값들이 전부 사라집니다!
앱을 삭제하지않는한 값을 보존해주는 AsyncStorage 저장소를 이용하도록 하겠습니다.
AsyncStorage 라이브러리를 install
해주었습니다.
> npm expo install @react-native-async-storage/saync-storage
AsyncStorage 에는 모든 date를 String
으로 저장해주어야하기 때문에, Json.stringify()
작업을 거쳐야합니다.
https://react-native-async-storage.github.io/async-storage/docs/usage/
해당페이지에서 살펴보면서 참고 코드 복붙..ㅎㅎ 하였습니다.
uise 에서 import
해주었고, hook
으로 만들어 사용해도 되고, AsyncStorage
함수 자체를 이용해도 됩니다. 저는 함수 자체를 이용하렿바니다.
주황색 네모의 주석처리한 부분을 먼저 보겠습니다.
setItem 의 인자로는 key
와 value
를 주어야합니다.
공통으로 사용할 TODO_LIST_KEY
를 가장 위에 선언해주었습니다.
value
는 String 형식으로 넣어주어야합니다.
newTodoList를 저장해주어야하는데 배열입니다.
JSON.stringify()
함수를 이용해서 String으로 저장해줍니다.
저장소에 TODO_LIST_KEY
를 가진 값인 newTodoList
가 String화 된 값으로 저장돼있습니다.
addTodo, removeTodo, toddleTodo에서 모두 사용해주어야하니 saveTodoList
로 새로 선언을 해준 후 사용하였습니다.
이제 앱을 종료해도 AsyncStorage 에 data
가 저장돼있기 때문에 문제없이 값을 가져올 수 있습니다.
getItem으로 KEY
만 가져와주면 사용이 가능합니다.
저장된 값을 세팅해주어야합니다.
Hook
이 선언되는 순간! 랜더링 직후에 딱 한번 실행되는 함수인 DidMount 역할을 해주는 await
을 이용해줍니다.
useEffect에서는 await
을 사용할 수 없기 때문에 init() 함수를 따로 만들어주었습니다.
init() 함수는 DidMount 시점에 실행되고, 이 곳에서 AsyncStorage에 저장된 데이터를 가져오는 작업을 해준 후 콘솔을 찍어 확인해보겠습니다.
저장된 값이 없기때문에 result null이 찍히네요!
Todo를 저장하고 리로드하여 앱을 재실행 해주었습니다.
Log에 등록한 Todo 들이 String 형태로 잘 담겨있는 모습입니다.
String으로 저장된 date를 parse
함수를 이용해 파싱해줍니다.
LOG를 보면 result
는 String타입, newTodoList
는 object타입인 것을 확인할 수 있습니다.
배열 타입도 Object 타입으로 표시됩니다.
이제 리로드를 해주어도 저장된 Todo가 그대로 보여집니다.
이렇게 TodoList + 캘린더 프로젝트를 마무리하겠습니다.
스크롤 부분과, 리로드시 데이터를 불러올 때 빈 Todo가 보이고 이후에 불러온 data 보여지는 오류가 있습니다.
후자는 사용자의 경험을 좋게해주기위해서 state나 indicate를 줘서 로딩 애니메이션을 추가하거나 로딩중입니다. 문구를 표시해주는 등의 해결방법이 있습니다.
추후에 많이 다루어야할테니 이번 프로젝트는 여기서 마무리.....!!!!!