목표: 현재 작성한 리덕스에서 오류는 아니지만
useSelector((state)=>state)처럼 같은 상태를 변환함으로
좋지 않다는 콘솔창의 메시지를 보고 다음과 같이 변경하여 불필요한 랜더링을 막는다.
변경 전 :
import { createSlice } from "@reduxjs/toolkit";
import { v4 as uuidv4 } from "uuid";
const counterSlice = createSlice({
name: "addTask",
initialState: [],
reducers: {
add: (state, action) => {
return [...state, action.payload];
},
},
});
export const { add } = counterSlice.actions;
export default counterSlice.reducer;
변경 후 :
import { createSlice } from "@reduxjs/toolkit";
import { v4 as uuidv4 } from "uuid";
const addSlice = createSlice({
name: "addTask",
initialState: {
todos: [],
},
reducers: {
add(state, action) {
const newTodo = action.payload;
state.todos.push({
id: uuidv4(),
title: newTodo.title,
date: newTodo.date,
file: newTodo.file,
category: newTodo.category,
todo: newTodo.todo,
});
},
},
});
export const addActions = addSlice.actions;
export default addSlice;
해당 컴포넌트에 useSelector를 사용하여 상태를 화면에 랜더링하는 부분
1) 리스트 map 랜더링 부분
const ToDoList = () => {
const list = useSelector((state) => state.addTask.todos);
console.log(list);
return (
<div id="myTodoSection">
<ScrollAnimationContainer>
<CardLayer>
<h2>To do List</h2>
<hr />
<CardList>
<EachCard>
{list?.map((todo) => {
return (
<div key={todo?.id}>
<TaskCard>
<StyledLink to={`/todo/${String(todo?.id)}`}>
<div>
<h3>{todo?.title}</h3>
</div>
<div>
<p>{todo?.date}</p>
</div>
<div>
<img
id="img"
src={todo?.file[0]}
alt="imgFile"
style={{ width: "150px", height: "150px" }}
/>
</div>
<div>
<p>{todo?.category}</p>
</div>
<div>
<p>{todo?.todo}</p>
</div>
<p>Read More</p>
</StyledLink>
</TaskCard>
</div>
);
})}
<AddButton>
<h2
onClick={() => {
window.scrollTo({
top: 550,
behavior: "smooth",
});
}}
>
add
</h2>
</AddButton>
</EachCard>
</CardList>
</CardLayer>
</ScrollAnimationContainer>
</div>
);
};
export default ToDoList;
2) 상세 페이지 부분
const TodoDetail = () => {
const { id } = useParams();
const list = useSelector((state) => state.addTask.todos);
console.log(list);
const selectedItem = list.find((item) => String(item.id) === String(id));
console.log("id는 이거다", id);
console.log("list는 이거다", list);
console.log("selectitem은 이거다", selectedItem);
if (!selectedItem) {
return (
<div>
<p>Todo not found</p>
</div>
);
}
return (
<DetailLayer>
<h2>{selectedItem?.title}</h2>
<hr />
<p>{selectedItem?.date}</p>
<div>
<img id="img" src={selectedItem?.file[0]} alt="imgFile" />
</div>
<p>{selectedItem?.category}</p>
<p>{selectedItem?.todo}</p>
</DetailLayer>
);
};
export default TodoDetail;