ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • connect
    개발/react 2020. 12. 20. 11:08

    connect 함수는 리액트 앱의 하위 컴포넌트에서 redux store를 접근하는 것을 가능하게 해주는 역할을 한다. 이 함수를 이용해서 컴포넌트 단에서 redux store에 접근하고 액션을 호출 할 수 있게 된다. 이번 포스트에서는 간단한 예제로 connect 함수를 통해 redux store를 사용하는 방법을 다뤄보려고 한다.

     

    0. 준비작업

     

    connect 함수 소개를 위해 예제와 텍스트와 숫자를 담당하는 redux를 만들었다.

     

    BlogStore.js

    import { createStore, combineReducers } from 'redux';
    
    const textReducerState = {
        text: '',
        name: 'textReducer'
    };
    
    const textReducer = (state = textReducerState, action) => {
        switch (action.type) {
            case 'SET_TEXT':
                return {
                    ...state,
                    text: action.text
                };
            default: 
                return state;
        }
    }
    
    const numberReducerState = {
        numberState: 30,
        name: 'numberReducer'
    };
    
    const numberReducer = (state = numberReducerState, action) => {
        switch (action.type) {
            case 'SET_NUMBER':
                return {
                    ...state,
                    number: action.number
                };
            default: 
                return state;
        }
    };
    
    export const configureStore = () => {
        const store = createStore(
            combineReducers({
                text: textReducer,
                number: numberReducer
            })
        );
        return store;
    };

     

    BlogActions.js

     

    export const setText = (
        text = ''
    ) => ({
        type: 'SET_TEXT',
        text
    });
    
    export const setNumber = (
        number = 0
    ) => ({
        type: 'SET_NUMBER',
        number
    });

     

     

    1. Provider 

     

    configureStore() 함수를 통해 store를 생성하고 Provider 태그에 store를 속성값으로 넣는다. 이러면 하위에 추가되는 component에서 redux store를 바라볼 수 있는 창구가 만들어진다.

     

    import React from 'react';
    import ReactDOM from 'react-dom';
    import { Provider } from 'react-redux';
    import { configureStore } from './BlogStore';
    import BlogMain from './BlogMain';
    
    const store = configureStore();
    
    
    const jsx = (
        <Provider store={store}>
            <BlogMain />
        </Provider>
    );
    
    
    ReactDOM.render(jsx, document.getElementById('app'));
    
    

     

    2. connect 

     

    하위 컴포넌트 단에서는 Provider에서 제공하는 store 함수를 connect 함수를 통해서 받아온다. 함수 형식이든 클래스 형식이든 받는 방식은 동일하다. 

     

     

    2.1 클래스형식

     

    import React from 'react';
    import { connect } from 'react-redux';
    import BlogDetail from './BlogDetail';
    
    
    class BlogMain extends React.Component {
        render() {
            console.log(this.props.text)
            console.log(this.props.number)
            return (
                <div>
                    <p>BlogMain component</p>
                    <BlogDetail />
                </div>
            )
        };
    };
    const mapStateToProps = (state) => {
        return {
            text: state.text,
            number: state.number
        }
    };
    export default connect(mapStateToProps)(BlogMain);

     

    클래스 형식 컴포넌트를 export 할 때 connect 함수를 사용하고 첫번째 인자에 mapStateToProps 함수를 넣었는데 redux store에 있는 값을 컴포넌트에 어떻게 넘겨줄지 세팅하는 작업이다.  넘겨 받은 값은 component의 props에 들어가서 호출 할 수 있다. 아래 사진은 render() 함수 안에서 console로 찍은 로그다. textReducer와 numberReducer가 출력되는 것을 볼 수 있다.

     

     

    2.2 함수 형식 

     

    import React from 'react';
    import { connect } from 'react-redux';
    
    const BlogDetail = (props) => (
        <div>
            <p>BlogTextDetail</p>
            <p>{props.text.name}</p>
        </div>
    );
    const mapStateToProps = (state) => {
        return {
            text: state.text
        };
    };
    
    export default connect(mapStateToProps)(BlogDetail)

     

    함수 형식도 크게 다르지 않다. 컴포넌트 내에서 호출 할 때 this를 부르지 않아도 된다는 점만 다르다. 위 코드로 호출하면 아래 그림처럼 화면 뷰가 그려진다.

     

     

    3. Action 

     

    connect로 컴포넌트에 전달 할 때 store만 전달 하는것이 아니라 action을 넣을 수 있는 dispatch 함수까지 전달된다. react 디바이스 툴을 사용해보면 component의 props 안에 dispatch가 들어있는 것을 확인 할 수 있다. 

     

     

    실제로도 잘 사용할 수 있을 지 테스트 해보자. 방금 전에 사용한 BlogDetail 컴포넌트를 살짝 수정해서 현재 store에 저장된 text를 출력하고 버튼을 추가하고 클릭하면 text를 BlogDetail로 바뀌도록 했다.

     

    import React from 'react';
    import { connect } from 'react-redux';
    import { setText } from './BlogActions';
    
    const BlogDetail = (props) => (
        <div>
            <p>BlogTextDetail</p>
            <p>current store text value: {props.text.text}</p>
            <button onClick={() => {
                props.dispatch(setText('BlogDetail'))
            }}>Change text to BlogDetail</button>
        </div>
    );
    
    const mapStateToProps = (state) => {
        return { text: state.text};
    };
    
    export default connect(mapStateToProps)(BlogDetail)

     

    함수를 실행하고 버튼을 클릭하니 화면이 아래와 같이 store의 text 값이 BlogDetail로 변경됐다.

     

     

    4. 총평 

     

    코딩을 처음 하는 분이면 이걸 왜 이렇게까지 해야할지 이해가 안될 수 있을 것 같은데 이전에 mvvm, mvc 패턴을 경험해본 개발자들에게는 redux가 크게 어려울 것 같지 않다. 강의 들을 때는 헷갈렸는데 실제로 코드로 짜보니까 어떤 식으로 구조를 잡아야할 지 느낌이 온다. 물론 자바스크립트 언어 특성상 state 세부 이름을 관리할 때 꽤 귀찮음을 겪을 것 같긴 하다.

    '개발 > react' 카테고리의 다른 글

    useEffect  (1) 2020.12.21
    useState  (0) 2020.12.21
    react router  (0) 2020.12.17
    redux  (0) 2020.12.16
    scss  (0) 2020.12.13

    댓글

Designed by Tistory.