리액트 톺아보기1 - Reducer

이지영·2025년 1월 10일

리액트 톺아보기 시작

스파르타 코딩클럽을 이수한 후 소속감이 사라졌다는 허전함이 있었지만,
혼자 천천히 편안하게 공부할 수 있는 시간이 되어서 한편으로는 좋았다.

휘몰아치는 강의와 팀프로젝트, 개인프로젝트, 과제에 허덕이느라 부족한 부분을 알고있지만 프로젝트 기간을 맞추기 위해 저 멀리 묻어놨던 것들을 하나하나 꺼내서 공부해보는 시간을 가져보려고 한다.

사실 빨리 개인프로젝트를 시작해서 해보고 싶었던것을 이것 저것 구현해보고 싶긴 하지만,
기초부터 탄탄하게 다져야 자신감도 생기고 막혔을때 수월하게 풀 수 있다.


먼저 수도 없이 많이 했던 TodoList 를 구현하는 것을 해보려고 한다.

한참 시간이 지나고 눈감고 코드를 짜려고 하면 버벅거리는 경우가 많아
이번 기회에 언제 다시 치더라도 정확하게 술술 칠 수 있길 바라는 마음으로
복습을 했다.

추가로 Reducer을 확실하게 이해하고 사용하고 싶었다.

State를 이용하여 TodoList를 구현하고
Reducer을 이용하여 TodoList를 구현해보려고 한다.

먼저 State를 이용하여 간단한 TodoList를 구현해보았다.

TodoList 생성

const [todos, setTodos] = useState(mockData);
const idRef = useRef(3);
const onCreate = (content) => {
	const newTodo = {
    	id: idRef.current ++,
      	isDone: false,
      	content: content,
      	date: new Date().getTime()
    }
    setTodos([newTodo,...todos])
}

TodoList 수정

체크박스의 토글 즉, isDone: ture -> false , false -> true 로 변경해주는 수정을 말함
해당하는 id값을 찾아서 수정해줘야하기 때문에 map을 사용한다.

const onUpdate = (targetId) => {
	setTodos(todos.map((item) => item.id === targetId ? {...item,isDone:!item.isDone} : item ))
}

TodoList 삭제

이번에는 리스트를 삭제해주는 함수를 작성해 보았다.
해당하는 아이디를 제외한 것들을 반환해줘야하기 때문에 filter을 사용해야한다.

const onDelete = (targetId) => {
	setTodos(todos.filter((item)=>item.id !== targetId))
}

이번에는 Reducer를 이용해보자

Reducer을 들어가기전에 State와의 차이점에 대해 간단하게 정리해보자면
둘은 비슷한 친구이다
하지만 State는 상태관리를 컴포넌트 내부에서 하지만
Reducer은 상태관리를 컴포넌트 외부로 분리할 수 있다.

가독성이 높아진다 : )
State로 구현된 함수들을 Reducer으로 변경해보자

Todo 생성 함수


const [todos, dispatch] = useReducer(reducer, mockData);

const onCreate = (content) => {
	dispatch({
    	type: "CREATE",
    	data: {
    		id: idRef.current ++,
        	isDone: false,
        	content: content,
        	date: new Date().getTime()
    	}
    })
}

function reducer (state, action) {
	switch(action.type){
      case "CREATE" :
        return [action.data, ...state]
    }
}

action은 dispatch객체를 갖는다.
그리고 해당하는 action의 타입별로 reducer가 동작한다.

Todo 수정 함수

// 수정은 해당하는 targetId의 값을 수정해야하므로 map함수 사용
const onUpdate = (targetId) => {
	dispatch({
    	type: "UPDATE",
      	targetId: targetId,
    })
}

function reducer (state,action) {
	switch(action.type) {
      case "CREATE" : 
        return [action.data, ...state]
      case "UPDATE" :
        return state.map((item)=>
                    item.id === action.targetId ? 
                    {...item, isDone: !item.isDone} :item)
    }
}

Todo 삭제 함수

const onDelete = (targetId) => {
	dispatch({
    	type: "DELETE",
        targetId: targetId
    })
}

function reducer (state,action) {
	switch(action.type) {
      case "CREATE" : 
        return [action.data, ...state]
      case "UPDATE" :
        return state.map((item)=>
                    item.id === action.targetId ? 
                    {...item, isDone: !item.isDone} :item)
      case "DELETE" : 
        return state.filter((item)=>
                     item.id !== action.targetId);
      default : 
        return state;
    }
}

형태로 state => reducer로 수정해주었다.

0개의 댓글