TIL/기록
[TIL] redux 문제
developeryeon
2024. 2. 8. 00:02
redux를 써서 todo-list 카드의 모음을 만드는데 제대로 만들지를 못해서 조금씩 써봤다.
파일 몇개는 생략하고 ..
// Home.jsx
const Home = () => {
return (
<div>
<InputArea />
<TodoList isActive={true}>
<TodoList isActive={false}>
</div>
)
}
export default Home;
이렇게 true 와 false를 써놓고
이렇게 써서 보면 item 안에는 todos 와 users 둘 다 있으니 여기서 todos만 빼보면, 우리가 처음 initialState로 지정했던 객체가 나온다.
그러면 이제부턴 객체를 추가하거나 삭제할땐 객체로 추가하거나 삭제하면 되겠다.
input 부분과 todo-list 부분을 분리하는 것에 대해서 나눠놨는데 우리가 이제는 데이터 어디서든지 접근하는것이 가능하기 때문에 굳이 props로 내려주지 않아도 된다.
우린 여기서 input 핸들링과 todo-list 핸들링을 따로 두자.
Todo-list는 isActive를 true로 할지, false로 할지에 따라서 결정할 수 있다.
// TodoList.jsx
const TodoList = ({ isActive }) => {
const todos = useSelector(function(item){
return item.todos;
})
// 이제 todos를 리스트 형태로 받아왔기 때문에 todos를 map으로 돌려주면 된다.
// isActive === false <- 투두리스트
// isActive === true <- 던리스트
return <div>
<h1>{isActive === true ? "투두리스트" : "던리스트"}</h1>
{todos.filter(function(todo) {
return todo.isDone !== true;
{/* 이게 헷갈리면 return todo.isDone === isActive; 랑 비교해보자.
만약 제목, 내용 텍스트가 던리스트에 가있으면 틀린것이다. */}
})
.map(function(todo) {
return (
<div>
<p>제목: {todo.title}</p>
<p>내용: {todo.body}</p>
<button>삭제</button>
<button>{isActive === true ? "완료" : "취소"}</button>
</div>
);
})}
</div>
}
export default TodoList;
true면 투두리스트, false면 던리스트를 주기로 했다.
// todos.js
// 어떤 버튼을 눌렀을 때, store에 접근해서 어떤 것을 변경하는 것 === 리듀서에서 변경을 일으키는 것
// 리듀서
const todos = (state = initialState, action) => {
switch (action.type) {
case "ADD_TODO":
// action.payload => { 새로운 todo Item }
const newTodoItem = action.payload;
return [...state, newTodoItem];
case "DELETE_TODO":
// payload로 id만 주게되면 그 id를 찾아서 삭제할 수 있다.
// action.payload => todo의 id
const deleteTargetId = action.payload;
const deleteFilteredList = state.filter(function (item) {
if (item.id === deleteTargetId) {
return false;
} else {
return true;
}
});
return deleteFilteredList;
case "SWITCH_TODO":
// action.payload => todo의 id
const switchTargetId = action.payload;
const switchMappedList = state.map(function (item) {
if (item.id === switchTargetId) {
return {
//내가 누른 객체가 여기 들어간다.
...item,
isDone: !item.isDone,
};
} else { // else는 눌린 값이 아닌 원래 있던 값이다. 바뀔 필요가 없다.
return item;
}
});
return switchMappedList;
default:
return state;
}
};
배열 / 객체가 다른 값이다를 구분하는 기준이 뭘까?
바로 객체가 바라보고 있는 주소값이다.
여기서 filter는 deleteFilteredList랑 state랑은 완전히 다르다. 왜? 완전히 다른 주소값을 쓰기 때문에!
이걸 이제 어떻게할까? InputArea를 통해 값을 넣었을 때, 그 값으로 계산해줄것이니까
//InputArea.jsx
const InputArea = () => {
const [title, setTitle] = useState("");
const [body, setBody] = useState("");
return (
<div>
<h3>값을 입력하는 곳이에요</h3>
<Input value={title} onChange={(e) => {
setTitle(e.target.value);
}}
/>
<Input value={body} onChange={(e) => {
setTitle(e.target.value);
}}
/>
<button
onClick={() => {
const newTodo = {
id: shortid, //shortid를 import 해오고나서
title: title,
body: body,
isDone: false,
};
dispatch({
type: "ADD_TODO",
payload: newTodo,
});
}}
>
입력
</button>
</div>
)
}
이렇게하면 완료 / 취소 버튼도 할 수 있다.
<p>제목: {todo.title}</p>
<p>내용: {todo.body}</p>
<button
onClick={() => {
dispatch({
type: "DELETE_TODO",
payload: todo.id,
})
}}>삭제</button>
<button
onClick={()=> {
dispatch({
type: "SWITCH_TODO",
payload: todo.id,
})
}}>{isActive === true ? "완료" : "취소"}</button>