반응형

들어가기 전

  • Controller에서 값 증가, 하락 버튼을 클릭한 경우 Display에서 변경된 값을 출력
  • Controller에서 색변경 버튼을 클릭한 경우 Display에 배경색을 랜덤으로 변경

redux란?

  • 상태, 이벤트를 글로벌하게 관리하는 방법 중 하나
  • 여러 계층의 컴포넌트간에 관계가 복잡하여 데이터를 주고받거나 조작하기 어려울 경우 사용함
  • Action : 이벤트 종류를 관리
  • Reducer : 이벤트에 해당하는 실제 행동을 관리

redux 라이브러리 설치

npm install redux react-redux

[Action] ActionType.js 코드 추가

  • 경로 : <프로젝트>/src/redux/action/ActionType.js
export const INCREMENT = "INCREMENT";
export const DECREMENT = "DECREMENT";
export const SET_COLOR = "SET_COLOR";

[Action] index.js 코드 추가

  • 경로 : <프로젝트>/src/redux/action/index.js
import * as type from './ActionType';

export function increment() {
    return {
        type: type.INCREMENT
    }
}

export function decrement() {
    return {
        type: type.DECREMENT
    }
}

export function setColor(color) {
    return {
        type: type.SET_COLOR,
        color: color
    }
}

[Reducer] changeNumber.js 코드 추가

  • 경로 : <프로젝트>/src/redux/reducer/changeNumber.js
import * as type from '../action/ActionType';

const initialState = {
    number: 0,
    dummy: 'test'
};

export default function changeNumber(state = initialState, action) {
    // state 값은 read-only 이므로 값을 통째로 복사한 후 변경된 값만 바꾸고 반환해야함
    // ...state : state 값을 통째로 복사
    switch (action.type) {
        case type.INCREMENT:
            return {
                ...state,
                number: state.number + 1
            };
        case type.DECREMENT:
            return {
                ...state,
                number: state.number - 1
            };
    }

    return state;
}

[Reducer] changeColor.js 코드 추가

  • 경로 : <프로젝트>/src/redux/reducer/changeColor.js
import * as type from '../action/ActionType';

const initialState = {
    color: [255, 255, 255]
};

export default function changeColor(state = initialState, action) {
    // state 값은 read-only 이므로 값을 통째로 복사한 후 변경된 값만 바꾸고 반환해야함
    // ...state : state 값을 통째로 복사
    switch (action.type) {
        case type.SET_COLOR:
            return {
                color: action.color
            }
    }

    return state;
}

[Reducer] index.js 코드 추가

  • 경로 : <프로젝트>/src/redux/reducer/index.js
import { combineReducers } from 'redux';
import changeColor from './changeColor';
import changeNumber from './changeNumber';

const reducers = combineReducers({
    changeColor, changeNumber
});

export default reducers;

[Component] Display.js 코드 추가

  • 경로 : <프로젝트>/src/component/Display.js
import React, { Component } from 'react';
import PropTypes from 'prop-types';

const propTypes = {
    number: PropTypes.number,
    color: PropTypes.array
};

const defaultProps = {
    number: -1,
    color: [0, 0, 0]
};

class Display extends Component {
    render() {
        const color = this.props.color;
        const style = {
            background: `rgb(${color[0]}, ${color[1]}, ${color[2]})`
        };

        return (
            <div style={style}>
                <h1>{this.props.number}</h1>
            </div>
        );
    }
}

Display.propTypes = propTypes;
Display.defaultProps = defaultProps;

export default Display;

[Component] Controller.js 코드 추가

  • 경로 : <프로젝트>/src/component/Controller.js
import React, { Component } from 'react';
import PropTypes from 'prop-types';

const propTypes = {
    onPlus: PropTypes.func,
    onSubtract: PropTypes.func,
    onRandomizeColor: PropTypes.func,
};

const defaultProps = {
    onPlus: () => console.warn('onPlus is not defined'),
    onSubtract: () => console.warn('onSubtract is not defined'),
    onRandomizeColor: () => console.warn('onRandomizeColor is not defined'),
};

class Controller extends Component {
    render() {
        return (
            <div>
                <button onClick={this.props.onPlus}>+</button>
                <button onClick={this.props.onSubtract}>-</button>
                <button onClick={this.props.onRandomizeColor}>Randomize Color</button>
            </div>
        );
    }
}

Controller.propTypes = propTypes;
Controller.defaultProps = defaultProps;

export default Controller;

[Component] App.js 코드 추가

  • 경로 : <프로젝트>/src/App.js
import React, { Component } from 'react';
import Display from './component/Display';
import Controller from './component/Controller';

import { connect } from 'react-redux';
import * as action from './redux/action/index';

class App extends Component {
    constructor(props) {
        super(props);

        this.setRandomColor = this.setRandomColor.bind(this);
    }

    setRandomColor() {
        const color = [
            Math.floor((Math.random() * 55) + 200),
            Math.floor((Math.random() * 55) + 200),
            Math.floor((Math.random() * 55) + 200)
        ];

        this.props.handleSetColor(color);
    }

    render() {
        return (
            <div>
                <Display
                    number={this.props.number}
                    color={this.props.color}
                />
                <Controller
                    onPlus={this.props.handleIncrement}
                    onSubtract={this.props.handleDecrement}
                    onRandomizeColor={this.setRandomColor}
                />
            </div>
        );
    }
}

const mapStateToProps = (state) => {
    return {
        number: state.changeNumber.number,
        color: state.changeColor.color
    }
};

const mapDispatchToProps = (dispatch) => {
    return {
        handleIncrement: () => { dispatch(action.increment()) },
        handleDecrement: () => { dispatch(action.decrement()) },
        handleSetColor: (color) => { dispatch(action.setColor(color)) }
    }
};

export default connect(mapStateToProps, mapDispatchToProps)(App);

[Component] index.js 코드 추가

  • 경로 : <프로젝트>/src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

import { createStore } from 'redux';
import { Provider } from 'react-redux';
import reducers from './redux/reducer/index';

const store = createStore(reducers);

ReactDOM.render(
    <Provider store={store}>
        <App/>
    </Provider>,
    document.getElementById('root')
);

참고

반응형

'Development > React' 카테고리의 다른 글

[React] Hooks  (0) 2019.05.15
[React] MobX  (0) 2019.05.14
[React] 기본 문법  (0) 2019.05.05
[React] Visual Studio Code 설정  (0) 2019.05.05
[React] 프로젝트 설정  (0) 2019.05.05

+ Recent posts