학습내용
- 삭제
- 완료/취소
- 수정
- 카테고리 설정
- async storage
edit
버튼 클릭시 기존에 작성했던 내용이 전부 사라지는 버그 발생
const [edit, setEdit] = useState("");
const setEditing = (id, title) => {
const newTodos = [...todos];
const i = todos.findIndex((todo) => todo.id === id);
newTodos[i].isEdit = !newTodos[i].isEdit;
setEdit(title);
setTodos(newTodos);
};
return (
(중략)
{todo.isEdit ? (
<TextInput
value={edit}
onChangeText={setEdit}
onSubmitEditing={() => editTodo(todo.id)}
/>
) : (
<Text style={styles.todoTitle}>{todo.title}</Text>
)}
<View style={styles.todoBtn}>
<TouchableOpacity onPress={() => setEditing(todo.id, todo.title)}>
(중략)
</TouchableOpacity>
edit 버튼을 클릭해도 기존의 내용이 사라지지 않도록 setEditing
가 실행될 때마다 setEdit
로 TextInput
의 상태를 변화시켰다.
<TextInput
defaultValue={todo.title}
onChangeText={setEdit}
onSubmitEditing={() => editTodo(todo.id)}
style={styles.editInput}
/>
TextInput
에 defaultValue={todo.title}
를 추가하면 title
을 매개변수로 가져와 setEdit
하는 방법보다 훨씬 간단하게 처리할 수 있다.
아무 내용도 변경하지 않고
done
버튼 클릭시 이전에 작성했던 내용으로 변경되는 버그 발생
const setEditing = (id, title) => {
setEdit(title);
const newTodos = [...todos];
const i = todos.findIndex((todo) => todo.id === id);
newTodos[i].isEdit = !newTodos[i].isEdit;
setTodos(newTodos);
};
defaultValue={todo.title}
를 적용하면서 기존의 코드를 지웠더니 이런 버그가 발생했다. 상태변화가 일어나지 않았기 때문이다. setEditing
이 실행될 때마다 다시 setEdit(title)
로 해당 투두리스트 내용으로 상태변화를 시켜주면 해결 완료.
로컬 데이터베이스를 이용할 수 있는 도구로 string 형태의 데이터만 관리 가능하다. 단, 객체 형태의 경우 저장시엔
JSON.stringify()
, 로딩시엔JSON.parse()
를 사용하면 async storage로 관리가 가능하다.
yarn add @react-native-async-storage/async-storage
공식문서
const setCate = async (cate) => {
setCategory(cate);
await AsyncStorage.setItem("category", cate);
};
// 투두리스트의 현재 상태를 AsyncStorage에 저장
useEffect(() => {
const saveTodos = async () => {
await AsyncStorage.setItem("todos", JSON.stringify(todos));
};
if (todos.length > 0) saveTodos();
}, [todos]);
// 최초 마운팅시 AsyncStorage에 저장했던 데이터 불러오기
useEffect(() => {
const getData = async () => {
const resTodos = await AsyncStorage.getItem("todos");
const resCate = await AsyncStorage.getItem("category");
setTodos(JSON.parse(resTodos) ?? []);
setCategory(resCate ?? "Study");
};
getData();
}, []);
setItem
데이터 추가, 수정시 사용getItem
일치하는 데이터 발견시 해당 데이터 로딩 or null
반환에러
리로드시 데이터 초기화
원인
const [todos, setTodos] = useState(initialState);
초기값이 async storage보다 더 우선적으로 사용되었기 때문
해결
const [todos, setTodos] = useState([]);
초기값 대신 빈 배열 부여