React

8. 확장성을 고려한 React 컴포넌트

하늘을난모기 2018. 12. 2. 18:23

8. 확장성을 고려한 React 컴포넌트

8.1 컴포넌트의 기본 속성

defaultProps를 정적 클래스 속성으로 추가

ex) defaultProps 예시

class Datepicker extends React.Component {
    ...
}
Datepicker.defaultProps = {
    currentDate: Date(),
    rows: 4,
    locale: 'US'
}

8.2 React 속성 타입과 유효성 검사

propTypes 정적 속성을 이용하여 속성 타입 설정

ex) propTypes 예시

class Datepicker extends React.Component {
    ...
}
Datepicker.propTypes = {
    currentdate: PropTypes.string,
    rows: propTypes.number,
    locale: PropTypes.oneOf(['US', 'CA', 'MX', 'EU'])
}

8.3 자식 엘리먼트 렌더링

ex) 자식 엘리먼트 속성 활용하기

class Content extneds React.Component {
    render() {
        return (
            <div className="content">
                {this.props.children}
            </div>
        )
    }
}

ReactDOM.render(
    <div>
        <Content>
            <h1>React</h1>
            <p>Rocks</p>
        </Content>
        <Content>
            <img src="" width="100"/>
        </Content>
    </div>,
    document.getElementById('content')
)

자식 엘리먼트가 하나라면 this.props.children은 배열이 아니다.

만약 문자열 자식 엘리먼트가 하나만 있을 때면 this.props.children.length를 사용할 경우 문자열 길이를 반환한다.

대신에 React.Children.count(this.props.children)을 사용하면 자식 엘리먼트의 수를 정확히 확인할 수 있다.

8.4 코드 재사용을 위한 React 고차 컴포넌트 생성하기

고차 컴포넌트 ; 다른 컴포넌트가 기능을 상속받는 패턴

고차 컴포넌트를 통해 코드 재사용이 가능

ex) 고차 컴포넌트 정의 방법

const LoadWebsite = (Component) => {
    ...
}

ex) 고차 컴포넌트 구현 예제

const LoadWebsite = ((Component) => {
    class _LoadWebsite extends React.Component {
        constructor(props) {
            super(props)
            this.state = {label: 'Run'}
            this.state.handleClick = this.handleClick.bind(this)
        }

        getUrl() {
            return '...'
        }

        handleClick(event) {
            let iframe = document.getElementById('frame').src = this.geturl()
        }

        componentDidMount() {
            console.log(ReactDOM.findDOMNode(this))
        }

        render() {
            console.log(this.state)
            return <Component {...this.state} {...this.props} />
        }
    }
    _LoadWebsite.displayname = 'EnhancedComponent'
    return _LoadWebsite
}

ex) 고차 컴포넌트 사용 예제

class Button extends React.Component {
    render() {
        return <button
            className="btn btn-primary"
            onClick={this.props.handleClick}>
            {this.props.label}
        </button>
    }
}

class Link extends React.Component {
    render() {
        return <a onClick{this.props.handleClick} href="#"> {this.props.label} </a>
    }
}

class Logo extends React.Component {
    render() {
        return <img onClick={this.props.handleClick} width="40" src="logo.png" href="#" />
    }
}

const EnhancedButton = LoadWebsite(Button)
const EnhancedLink = LoadWebsite(Link)
const EnhancedLogo = LoadWebsite(Logo)
class Content extends React.Component {
    render() {
        return (
            <div>
                <EnhancedButton />
                <br />
                <EnhancedLink />
                <br />
                <EnhancedLogo />
                <br />
                <iframe id="frame" src= "" width="600 height="500" />
            </div>
        )
    }
}

ReactDOM.render(
    <Content />,
    document.getElementById('content')
}

8.5 모범 사례: 프레젠테이션 컴포너트와 컨테이너 컴포넌트

프레젠테이션 컴포넌트는 보통 DOM과 스타일에 구조만 추가

프레젠테이션 컴포넌트는 속성을 사용하지만 상태를 갖는 경우는 없다.

요약

  • 컴포넌트의 defaultProps 속성을 이용해서 모든 컴포넌트 속성의 기본값을 정의할 수 있다.
  • 난독화를 거치지 않은 개발 버전의 React 라이브러리를 사용할 때는 컴포넌트 속성 값의 유효성 검사를 강제할 수 있다.
  • 속성의 타입을 지정하고, isRequired를 추가하여 필수 속성으로 정할 수 있다. 필요하다면 속성 유효성 검사를 직접 정의할 수도 있다.
  • 속성 값이 유효성 검사를 통과하지 못하면 브라우저의 콘솔에 경고 메시지를 출력한다.
  • 난독화를 거친 프로덕션 버전의 React 라이브러리는 유효성 검사를 포함하지 않는다.
  • React에서 고차 컴포넌트를 생성하여 공통 속성, 메섣,, 이벤트를 캡슐화할 수 있다.
  • 고차 컴포넌트는 다른 컴포넌트를 인자로 받는 함수로 정의된다. 여기서 인자로 전달된 컴포넌트는 고차 컴포넌트로부터 상속받는다.
  • JSX에 중첩된 HTML 또는 React 컴포넌트는 부모 컴포넌트의 children 속성을 통해 접근할 수 있다.