3-1. Redux: 프로젝트 준비하기 - create-react-app

  • create-react-app 페이스북에서 만든 리액트 생성 도구이며 복잡한 설정없이 손쉽게 사용 가능
  • boilerplate 기본환경을 제공해주는 오픈소스
  • 파일이 저장될 때마다 번들링 해주며, 오류, 경고도 체크해 준다.
$ npm install -g create-react-app // $ yarn global add create-react-app
$ create-react-app 프로젝트명
$ cd 프로젝트명
$ npm start // yarn으로 설치한 사용자는 `yarn start`

Starting the Server http://localhost:3000/

$ npm install --save redux react-redux  // react-redux: 뷰 레이어 바인딩. Redux를 더 편하게 사용 할 수 있음

3-2. Redux: 프로젝트 구조 및 컴포넌트 생성

  • [Atom 에디터 - 패키지 설치] ESLint: linter-eslint

폴더 생성

src
    - actions
    - components
        - App.js
    - reducers

Airbnb React/JSX Style Guide

How to define propTypes, defaultProps, contextTypes, etc…

import React, { PropTypes } from 'react';

const propTypes = {
  id: PropTypes.number.isRequired,
  url: PropTypes.string.isRequired,
  text: PropTypes.string,
};

const defaultProps = {
  text: 'Hello World',
};

class Link extends React.Component {
  static methodsAreOk() {
    return true;
  }

  render() {
    return <a href={this.props.url} data-id={this.props.id}>{this.props.text}</a>
  }
}

Link.propTypes = propTypes;
Link.defaultProps = defaultProps;

export default Link;

Redux를 사용한 카운터 만들기

참고소스

기능

  • 버튼 1: 값 1씩 증가
  • 버튼 2: 값 1씩 감소
  • 버튼 3: 배경화면 색상 랜덤화

필요한 컴포넌트

: 기본 카운팅 -1, 증가, 증감, 배경컬러 버튼 3개

  • Value.js 숫자를 보여주는 컴포넌트 (멍청한(Dumb) 컴포넌트)
  • Control.js 버튼 3개 보여주는 컴포넌트 (멍청한(Dumb) 컴포넌트)
  • Counter.js Value.js, Control.js 담고 있는 부모 컴포넌트 (똑똑한(Smart) 컴포넌트)
// App.js
import React from 'react';
import Counter from './Counter';

const propTypes = {
};

const defaultProps = {
};

class App extends React.Component {

    render() {
        return (
            <Counter />
        );
    }
}

App.propTypes = propTypes;
App.defaultProps = defaultProps;

export default App;
// Value.js
import React, { Component, PropTypes } from 'react';

const propTypes = {
    number: PropTypes.number
};

const defaultProps = {
    //기본값
    number: -1
};

class Value extends React.Component {

    constructor(props) {
        super(props);
    }

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

Value.propTypes = propTypes;
Value.defaultProps = defaultProps;

export default Value;
// Control.js

import React, { Component, PropTypes } from 'react';

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

function createWarning(funcName) {
    return () => console.warn(funcName + ' is not defined');  //기본값 : 함수가 설정 되지 않았다고 경고를 띄움
}

const defaultProps = {
    onPlus: createWarning('onPlus'),
    onSubtract: createWarning('onSubtract'),
    onRandomizeColor: createWarning('onRandomizeColor')
};

class Control extends React.Component {
    constructor(props) {
        super(props);
    }

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

Control.propTypes = propTypes;
Control.defaultProps = defaultProps;

export default Control;
// Counter.js
import React, { Component, PropTypes } from 'react';
import Value from './Value';
import Control from './Control';

const propTypes = {

};

const defaultProps = {

};

class Counter extends React.Component {

    constructor(props) {
        super(props);
    }

    render() {
        return (
            <div>
                <Value />
                <Control />
            </div>
        );
    }
}

Counter.propTypes = propTypes;
Counter.defaultProps = defaultProps;

export default Value;

code & view