순수 Redux에서 React-Redux까지 정리

이주영·2023년 10월 19일
0

상태관리

목록 보기
1/1
post-thumbnail

들어가기 앞서

처음 입사를 하고 회사의 대시보드와 관련된 과제를 부여받았다. 그 안에 class형 컴포넌트, react-redux 여러 가지 새로운 것들이 있어 새로운 것들을 많이 배울 수 있었다. 그래서 이번 포스트에서 redux를 왜 좋은지 과거에 어떤 문제들을 해결했고 그 과정 가운데 어떤 새로운 문제가 등장하여 결과적으로 react-redux 라이브러리가 왜 좋은지에 대해 정리해보고자 한다.

소스 코드 : https://github.com/CodyMan0/reduxPrinciple (commit별 코드 참고)

학습 이유

대시보드를 만드는데 react-redux가 사용된다. 과제를 진행하면서 redux의 connect API를 제대로 알지 못해 불필요한 문제를 마주하게 돼, redux의 동작 원리와 개념을 잡아야 함을 알게 돼 10월 19일 오전 시간을 할애하여 정리하고자 함.


Redux란?

정의

공식문서가 말하는 정의 : 예측가능하고 중앙집권적이며 디버깅에 용이하고 유연한 상태관리 라이브러리.

개요

즉 리덕스가 하는 일은 어플리케이션의 복잡성을 낮춰서 개발자로 하여금 예측 가능하게 만들어주는 역할이다.

  • 리덕스는 하나의 상태를 갖는다.
state = {
	contents : [
		 {id : 1 ...},
		 {id : 2 ...}
	],
	selected_id : 2
}
  • 어플리케이션 전반에 하나의 상태로 존재하기에, 아무렇게 접근하거나 수정할 수 없는 규칙이 존재한다.
  • 리덕스에서는 Store는 핵심이다.

Redux Store (핵심)

스토어 안에는 총 5가지의 요소가 있다.

  1. state : 하나의 상태 객체가 내부에 존재한다.
  2. reducer : 이전 상태 값과 새로운 action, 두개의 인자를 이용해서 새로운 상태값으로 불변하게 만들어서 리턴하는 역할을 수행한다.
function reducre(state, action) {
  if(action.type === 'create'){
  const new Contents = oldState.contents.concat();
  const newMaxId = oldState.maxId + 1
  newContents.push({id:newMaxId, title : action.payload})
  return Object.assign({}, state, {
      contents:newContents,
      maxId : newMaxId,
      mode: 'read',
      selectedId:newMaxId
		})	
    }
}
  1. dispatch : UI단에서 상태를 변경해주는 역할을 수행한다.
		<form
  1. subscribe : 구독이란 의미이고 render함수를 상태에 구독시킨다면 상태가 바뀔때마다 UI가 다시 그려지게 할 수 있다.
  2. getState : State의 상태를 UI단에서 Read할 수 있도록 허용해주는 API이다.

스토어 외부에는 render 함수가 존재한다.

  1. render : render는 state를 참고해서 UI를 만들어주는 역할을 수행한다.
function render() {
var state = store.getState();

document.querySelector('#app').innerHTML = `
	<h1>WEB<h1>
`}

Redux in React (핵심)

redux를 리액트안에서 사용하면 컴포넌트와 redux Store의 결합도가 높아져 재활용이 어려워져 버리는 문제가 발생했다. 이를 해결하기 위해

  • 문제 store과 관련한 데이터를 컴포넌트에 주입하는 순간, 해당 컴포넌트를 재활용하지 못하는 문제가 생김.
  • 해결
  1. container presentational pattern을 활용해서 컴포넌트를 상위에서 감싸는 컴포넌트를 만들어 redux로부터 상태를 받아 내려주는 역할을 감당하는 컴포넌트를 다시 만들어야 했다. redux를 사용하는 이유는 복잡하지 않고 예측할 수 있는 애플리케이션을 만들기 위함인데 점점 코드의 양도 많아지고 복잡해지는 문제가 발생했다. 그래서 이 문제를 react-redux가 손쉽게 해결한다.

React-redux in React (핵심)

  • 해결

기존 리액트에서 redux를 도입하기 위해 또 다른 컨테이너를 만들었고 이벤트에 dispatch를 해야 하는 경우는 이벤트에 추가로 걸어주어야 했다. props로 상태를 전달할때는 store에 구독해서 store의 데이터가 바뀌면 리렌더링하는 코드를 작성해야 했다 핵심은 react-redux 라이브러리에서는 connect API를 제공해주는다는 것이다.

connect 함수 소스 코드를 살펴보면

function connect(mapStateToProps, mapDispatchToProps) {
  return function ( WrappedComponent) {
		return class extends React.Componenet {
			render() {
				return (
					<WrappedComponent
						{...this.props}
						{...mapStateToProps(store.getState(),this.props)}
						{...mapDispatchToProps(store.dispatch(),this.props)}
						/>
				)
			}
		}
  // 컴포넌트가 실제로 적용될때 호출
  // 이 코드로 인해서 상태가 바뀌면 UI에 반여된다.  
  componentDidMount(){
		this.unsubscribe = store.subscribe(this.handleChange.bind(this))
  }
  
  //컴포넌트가 제거 될때 호출
  componentWillUnMount(){
		this.unsubscribe()
  }
  
  handleChange({
  this.forceUpdate()	
		})
  }
}

제공해주는 connect API를 통해 상위 컴포넌트를 만들지 않아도 될 뿐만 아니라 컴포넌트의 생명 주기에 따라 구독을 등록하고 제거하는 로직도 구현되어있다. 현재는 useSelector와 useDispatch와 같은 Hook을 활용하여 더욱 쉽게 컴포넌트에서 Store의 값에 접근하고 수정할 수 있다. 이로써 Redux를 정리해보았고 조금씩 개념에 대한 이해도를 높여 복잡한 상태를 어렵지 않게 관리할 수 있도록 연습 해야겠다.

관련 있는 개념

  1. Flux 패턴
  2. 순수 함수

참고 자료

  1. 생활 코딩 리덕스편
  2. 생활 코딩 react-redux편
  3. 공식 문서

마무리

추가 예정

profile
https://danny-blog.vercel.app/ 문제 해결 과정을 정리하는 블로그입니다.

0개의 댓글