[Redux] React-redux

Wonhyun Kwon·2023년 6월 5일
0

Redux

목록 보기
3/5
post-thumbnail

1. React-redux 란?

ReduxReact와 연동해서 사용하기 편리하도록 만든 공식적인 라이브러리이다.

Redux 는 독립적인 도구이다. React 역시 독립적인 도구이다. 한마디로 이 둘을 서로 연결하는 도구가 바로 React-redux 이다.

물론, 이전 글에서 포스트한 기본적인 ReduxReact에서 사용 가능하다.
하지만, React 관점에서 더 편하게 사용하기 위해 React-redux 를 사용한다.




2. Redex vs React-redux

  • 공통점
    store ➡️ component ➡️ action ➡️ dispatch ➡️ reducer ➡️ store 순서는 동일하다.

  • 차이점
    react-reduxstore ➡️ component , component ➡️ action 단계에서 connect 라는 함수를 사용한다.




3. 기본 개념

React-redux 에 중요한 4가지 요소가 있다.

1) Provider

state'어떤 컴포넌트들에게 제공할 것인가?' 에 대한 가장 바깥쪽에서 알려주는 큰 울타리를 정의하는 컴포넌트이다.
Provider 의 Props 중에 store 를 반드시 정의해줘야 한다. 이름에서 알 수 있다시피 ReduxcreateStore 로 만든 store 를 집어 넣어 준다.

아래 예제를 보면 Provider 로 감싸진 ParentComponent 라는 이름의 컴포넌트는 store 가 가진 상태를 사용할 수 있다.
그렇다면 ParentComponent 의 하위 컴포넌트인 ChildComponent 역시 store 에 담긴 데이터를 사용할 수 있는 것이다.

import {SafeAreaView, Text, View} from 'react-native';
import {createStore} from 'redux';
import {Provider, useSelector, useDispatch, connect} from 'react-redux';

function App(): JSX.Element {
  const reducer = (currentState: any, action: any) => {
    if (!currentState) {
      return {
        number: 1,
      };
    }
    const newState = {...currentState};
    return newState;
  };

  const store = createStore(reducer);

  return (
    <Provider store={store}>
      <ParentComponent />
    </Provider>
  );
}

const ParentComponent = () => {
  return (
    <SafeAreaView>
      <ChildComponent />
    </SafeAreaView>
  );
};

const ChildComponent = () => {
  const number = useSelector(state => state.number);

  return (
    <View>
      <Text>{number}</Text>
    </View>
  );
};

export default App;

2) useSelector

store 가 가지고 있는 상태들 중에 '어떤 상태를 가져다 쓸래?' 에 대한 역할을 담당한다.

사용 방법은 간단하다.
아래 예제와 같이 상태를 가져다 쓰고 싶은 컴포넌트 안에서 useSelector 를 호출한 후 어떤 state 를 가져다 쓸 것인지 return 해주면 된다.

const ChildComponent = () => {
  const number = useSelector(state => state.number);

  return (
    <View>
      <Text>{number}</Text>
    </View>
  );
};

❗️여기서 중요한 점은, 상위 컴포넌트인 ParentComponent 로 부터 props를 전달 받아 사용하는 것이 아니라, ChildComponent 에서 곧장 state 를 호출하여 사용했다는 점이다. 이는 Redux 에서 Props drilling 이슈와 관련된다.


3) useDispatch

action 을 통해 reducer 를 호출하여 state 를 변경하는 메소드이다.

다음 예제처럼 버튼을 클릭했을 때, number 가 +1 씩 증가하는 기능을 만들어보자.

const ChildComponent = () => {
  const number = useSelector(state => state.number);
  const dispatch = useDispatch();

  return (
    <View>
      <Text>{number}</Text>
      <Button
        title="+"
        onPress={() => {
          dispatch({
            type: 'INCREASE',
          });
        }}></Button>
    </View>
  );
};

useDispatch 메소드를 호출하고 그 안에 action 객체 타입을 넣는다.

버튼을 누르는 순간 dispatch 가 동작하게 되고, reducer 가 호출되된다. action 에서 호출한 type 에 맞게 조건문이 발동하면서 state 가 변경되고, 변경을 감지한 store 가 상태를 업데이트 하게 되며 최종적으로 number 는 +1 이 되어 화면에 나타난다.

  const reducer = (currentState: any, action: any) => {
    if (!currentState) {
      return {
        number: 1,
      };
    }
    const newState = {...currentState};

    if (action.type === 'INCREASE') {
      newState.number++;
    }
    return newState;
  };

🔔 참고
const newState = {...currentState} 에서 state 를 복사하는 이유는 '상태의 불변성 법칙' 때문에 그렇다.
React 또는 React Native 에서는 상태를 직접적으로 변경할 수 없다. 상태를 변경하기 위해선 원본을 복사하여 복사본을 수정한 후, 그 것을 원본과 비교하여 변경 된 부분만 상태를 업데이트하기 때문에 위 같은 코드가 들어간 것이다.


4) connect

connectChildComponent 와 같이 하위 컴포넌트에서 store 에 접근하기 위해 사용되는 또 다른 메소드이다.
결론적으로, useSelectoruseDispatch 가 워낙에 편하기 때문에 사실 사용 할 일이 별로 없다. 따라서 깊이 안들어가기 위해 따로 예제도 다루지 않겠다.

profile
모든 사용자가 만족하는 UI를 만드는 FE 개발자 권원현입니다.

0개의 댓글