[React]Redux 써보기

Hyodduru ·2022년 5월 6일
1

React

목록 보기
17/22
post-thumbnail

2차 프로젝트 때 리덕스를 써먹어보지 못한 아쉬움이 컸다. 🥲
리액트 프로젝트를 할 때 항상 state를 내려주고 또 내려주고, 다시 최상단 부모로 끌어올려주고 복잡하고 귀찮은 작업들을 많이 하다보니, 리덕스나 혹은 context API를 쓸 줄 안다면 더 효율적으로 상태관리를 할 수 있지 않을까 싶었다.

그.래.서 이번 기업협업 프로젝트에서만큼은 꼭 리덕스를 써봐야겠다는 생각을 했다!

시작하기전 간단히 redux 관련 개념 알아보기

👉 Action : 상태 변화에 대한 의도를 표현하는 단순한 자바스크립트 객체 (type, payload)이란 property를 가져야함!! Type : 내가 뭘할건지에 대한 행위
👉 Action Creator : 이러한 action 객체를 정해진 틀에 맞게 리턴하는 단순한 함수.
🔖 Action 은 store에 담긴 데이터를 변형시킬 수 있는 유일한 법
👉 Provider : react app 전체에 제공할 store를 주입하는 장소
👉 useSelector : store 가져오는 역할 (state)
👉 useDispatch : action을 reducer로 보내는 역할 (setState)
👉 Reducer : (previousState, action) => newState 의 형태를 가지고 순수함수이며 예측 가능해야함, 값을 받아 하나의 결과물로 줄인다고 하여 reducer임

Action (추가, 삭제 등등)=> dispatcher(전달자 느낌) => store(action을 받고 행위를 해줌) => view (그 행위를 보여줌)

👉 위의 흐름으로 전역상태 관리가 이루어진다.

해결해야했던 문제🧐


참고) 아직 디자인이 다 나오지 않아서 화면은 미완성 상태임... ^^*

  1. 채팅 웹에서 chats, contacts, profile 메뉴 클릭 시 각각에 해당하는 컴포넌트를 보여주고 싶음.
  2. navigate를 사용하지 않고(page 이동을 하지 않고) 해당 기능을 구현하고 싶음.

이때 보여주고 싶은(return하고 싶은) 컴포넌트를 state로 넣고 redux를 활용하여 전역으로 상태관리를 해줄 수 있지 않을까 생각했다.

문제 해결 과정✨

  1. 가장 최상단 부모인 index.js 내에서 action type에 따라 원하는 component를 state로 지정해주는 reducer을 만들어준다.
// index.js
const reducer = (state = <ChatList />, action) => {
  switch (action.type) {
    case 'chatList':
      return <ChatList />;
    case 'contacts':
      return <Contacts />;
    case 'profile':
      return <Profile />;

    default:
      return state;
  }
};
  1. createStore로 store를 만든다.
    🔖 참고) reducer에서 새로운 state값 반환하면 store에 저장되어있는 현재 state값이 업데이트된다.
// index.js
const store = createStore(reducer, [<ChatList key="0" />]);
  1. Provider을 불러온 후, 연동할 컴포넌트를 감싸준 후 (App.js) Provider 컴포넌트의 props로 store 값을 설정해준다.

🔖 참고) Provider 는 react-redux 라이브러리에 내장되어있는, 리액트 앱에 store 를 손쉽게 연동 할 수 있도록 도와주는 컴포넌트이다.

// index.js
const root = ReactDOM.createRoot(document.getElementById('root'));

root.render(
    <Provider store={store}>
      <React.StrictMode>
        <App />
      </React.StrictMode>
    </Provider>
);
  1. 상태 값을 변화시켜야 하는 컴포넌트(Nav)에서 useDispatch hook을 활용하여 상태값을 변화시켜준다. (onClick event를 활용하여 해당 menu click시 해당 action type으로 변화시켜줄 것임)
// Nav.js 관련없는 코드 생략 
import { useDispatch } from 'react-redux';
const Nav = () =>{
  const dispatch = useDispatch();
  
  const showPage = pageName => {
    if(pageName === CHATS_MENU) dispatch({type :'chatList'});
    if(pageName === CONTACTS_MENU) dispatch({type :'contacts'});}
  
  return (  
          <ul className="nav__items">
        {NAV_DATA.map(({ id, icon, name, count }) => {
    		  <li
              key={id}
              onClick={() => {
                showPage(name);
               }
            >
              {icon}
            </li>)}</ul> )}

const CHATS_MENU = 'chats';
const CONTACTS_MENU= 'contacts';
  1. useSelector hook을 활용하여 state 값을 가져온 뒤 해당 값을 원하는 컴포넌트 내(ListContainer.js)에서 return해준다.
import { useSelector } from 'react-redux';
const ListContainer = () => {
  const selectedPage = useSelector(state => state);

  return <div>{selectedPage}</div>;
};

export default ListContainer;

🔖 참고) ListContainer는 Nav와 함께 App 안에 있던 아이.

const App = () => {
	return(
      <div className = "App">
      <Nav />
      <ListContainer />
      </div>)
 }      

🍯 마무리

아무튼 이렇게 해결했다!
리덕스를 활용함으로써 불필요하게 ListContainer 내에서 조건식을 따로 써주지 않고 useSelector를 활용해 해당 state를 바로 return해줄 수 있어 편했다. 리덕스를 쓰지 않았다면 useState hook을 활용해서 state를 일일히 내려주고 다시 끌어올려주는 과정들을 반복했을 텐데, 그런 과정을 다 생략할 수 있어서 좋았다.

profile
꾸준히 성장하기🦋 https://hyodduru.tistory.com/ 로 블로그 옮겼습니다

0개의 댓글