>  기사  >  웹 프론트엔드  >  React 구성 요소를 분해하는 몇 가지 고급 방법

React 구성 요소를 분해하는 몇 가지 고급 방법

小云云
小云云원래의
2018-02-09 16:40:362215검색

React 구성 요소는 끝없이 마술적이고 매우 유연합니다. 우리는 부품 설계에 많은 트릭을 사용할 수 있습니다. 그러나 구성 요소의 단일 책임 원칙을 보장하는 것이 매우 중요합니다. 이를 통해 구성 요소를 더 간단하고 편리하게 유지 관리할 수 있으며, 더 중요하게는 구성 요소를 더 재사용할 수 있게 만들 수 있습니다. 이 기사에서는 주로 React 구성 요소를 분해하는 몇 가지 고급 방법을 공유하여 도움이 되기를 바랍니다.

그러나 복잡하고 부풀어 오른 React 구성 요소를 어떻게 분해하는지는 간단한 문제가 아닐 수 있습니다. 이 글에서는 React 컴포넌트를 얕은 것부터 깊은 것까지 분해하는 세 가지 방법을 소개합니다.

방법 1: render() 메서드 잘라내기

이것은 생각하기 가장 쉬운 방법입니다. 구성 요소가 많은 요소를 렌더링할 때 이러한 요소의 렌더링 논리를 분리해야 합니다. 가장 빠른 방법은 render() 메서드를 여러 하위 렌더링 메서드로 분할하는 것입니다.

다음 예제를 보면 더 직관적일 것입니다.

class Panel extends React.Component {
    renderHeading() {        // ...
    }

    renderBody() {        // ...
    }

    render() {        return (
            <div>
                {this.renderHeading()}
                {this.renderBody()}
            </div>
        );
    }
}

주의깊은 독자라면 이것이 실제로 구성 요소 자체를 분해하지 않는다는 것을 금방 알 수 있을 것입니다. Panel 구성 요소는 여전히 원래 상태, props 및 클래스 메서드를 유지합니다.

구성요소 복잡성을 실제로 줄이는 방법은 무엇입니까? 몇 가지 하위 구성 요소를 만들어야 합니다. 이때 최신 버전의 React에서 지원하고 권장하는 기능적 구성 요소/상태 비저장 구성 요소를 채택하는 것은 확실히 좋은 시도가 될 것입니다.

const PanelHeader = (props) => (    // ...);const PanelBody = (props) => (    // ...);class Panel extends React.Component {
    render() {        return (
            <div>                // Nice and explicit about which props are used
                <PanelHeader title={this.props.title}/>
                <PanelBody content={this.props.content}/>
            </div>
        );
    }
}

이전 방법과 비교하면 이러한 미묘한 개선은 혁명적입니다.

PanelHeader와 PanelBody라는 두 가지 새로운 단위 구성 요소를 만들었습니다. 이는 테스트의 편의성을 제공하며, 다양한 구성요소를 개별적으로 직접 테스트할 수 있습니다. 동시에 React의 새로운 알고리즘 엔진인 React Fiber의 도움으로 두 단위 구성 요소의 렌더링 효율성이 크게 향상될 것으로 낙관적으로 기대됩니다.

방법 2: 템플릿 구성 요소

문제의 시작점으로 돌아가서 구성 요소가 왜 비대해지고 복잡해지는 걸까요? 하나는 많은 중첩된 렌더링 요소가 있다는 것이고, 다른 하나는 구성 요소 내에 많은 변경 사항이 있거나 여러 구성이 있다는 것입니다.

이 시점에서 구성 요소를 템플릿으로 변환할 수 있습니다. 상위 구성 요소는 템플릿과 유사하며 다양한 구성에만 중점을 둡니다.

더 명확하게 이해할 수 있도록 예를 들어야 합니다.

예를 들어, 여러 동작이나 이벤트가 있는 Comment 구성 요소가 있습니다.

동시에 구성 요소에 표시되는 정보는 사용자의 신원에 따라 변경됩니다.

  • 사용자가 이 댓글의 작성자인지 여부

  • 이 댓글이 올바르게 저장되었는지 여부; 권한

  • 잠깐만요...

  • 으로 인해 이 구성요소의 표시 동작이 달라집니다.

  • 이때 모든 로직을 혼동하는 것보다 더 나은 접근 방식은 React를 사용하여 React 요소의 특성을 구성 요소 간에 전달하여 더 강력한 템플릿처럼 만드는 것입니다.
class CommentTemplate extends React.Component {
    static propTypes = {        // Declare slots as type node
        metadata: PropTypes.node,
        actions: PropTypes.node,
    };

    render() {        return (            <div>                <CommentHeading>                    <Avatar user={...}/>

                    // Slot for metadata                    <span>{this.props.metadata}</span>                </CommentHeading>                <CommentBody/>                <CommentFooter>                    <Timestamp time={...}/>

                    // Slot for actions                    <span>{this.props.actions}</span>                </CommentFooter>            </div>
            ...
        )
    }
}

현재 실제 Comment 구성 요소는

class Comment extends React.Component {
    render() {        const metadata = this.props.publishTime ?        <PublishTime time={this.props.publishTime} /> :        <span>Saving...</span>;        const actions = [];        if (this.props.isSignedIn) {
            actions.push(<LikeAction />);
            actions.push(<ReplyAction />);
        }
        if (this.props.isAuthor) {
            actions.push(<DeleteAction />);
        }

        return <CommentTemplate metadata={metadata} actions={actions} />;
    }
}

metadata로 구성되어 있으며 작업은 실제로 특정 상황에서 렌더링되어야 하는 React 요소입니다.

예:

this.props.publishTime이 존재하는 경우 메타데이터는 ;

  • 그렇지 않으면 Saving입니다.. .< ;/span>.

  • 사용자가 로그인한 경우 렌더링해야 합니다(즉, actions 값은) ; 렌더링해야 하는 콘텐츠를 추가해야 합니다<

  • 방법 3: 고차 구성 요소

  • 실제 개발에서 구성 요소는 종종 다른 요구 사항으로 인해 오염됩니다.
  • 시나리오를 상상해 보세요. 페이지에 있는 모든 링크의 클릭 정보를 계산하려고 합니다. 링크를 클릭하면 통계 요청이 전송되는데, 이 요청에는 이 페이지 문서의 id 값이 포함되어야 합니다.

  • 일반적인 접근 방식은 문서 구성 요소의 수명 주기 함수인 componentDidMount 및 componentWillUnmount에 코드 논리를 추가하는 것입니다.
class Document extends React.Component {
    componentDidMount() {
        ReactDOM.findDOMNode(this).addEventListener(&#39;click&#39;, this.onClick);
    }

    componentWillUnmount() {
        ReactDOM.findDOMNode(this).removeEventListener(&#39;click&#39;, this.onClick);
    }

    onClick = (e) => {        // Naive check for <a> elements        if (e.target.tagName === 'A') { 
            sendAnalytics('link clicked', {                // Specific information to be sent
                documentId: this.props.documentId 
            });
        }
    };

    render() {        // ...
    }
}</p>
<h2> 이에 대한 몇 가지 문제는 다음과 같습니다. </h2>
<p></p>
<p>자체 기본 논리 외에도 기본 페이지 표시, 관련 컴포넌트 Document 다른 통계 로직이 있습니다. </p>
<p></p>
<p>Document 컴포넌트의 수명 주기 기능에 다른 로직이 있으면 이 컴포넌트는 더욱 모호해지고 불합리해집니다. </p>
<ul class=" list-paddingleft-2">
<li><p>통계 로직 코드는 재사용할 수 없습니다. </p></li>
<li> <p>부품 재구성 및 유지 관리가 더욱 어려워집니다. </p>
</li>
<li>
<p>이 문제를 해결하기 위해 우리는 고차 부품의 개념인 HOC(고차 부품)를 제안했습니다. 이 용어를 모호하게 설명하지 않고 고차 컴포넌트를 사용하여 위 코드를 재구성하는 방법을 직접 살펴보겠습니다. </p>
<pre class="brush:php;toolbar:false">function withLinkAnalytics(mapPropsToData, WrappedComponent) {    class LinkAnalyticsWrapper extends React.Component {
        componentDidMount() {
            ReactDOM.findDOMNode(this).addEventListener('click', this.onClick);
        }

        componentWillUnmount() {
            ReactDOM.findDOMNode(this).removeEventListener('click', this.onClick);
        }

        onClick = (e) => {            // Naive check for <a> elements            if (e.target.tagName === 'A') { 
                const data = mapPropsToData ? mapPropsToData(this.props) : {};
                sendAnalytics('link clicked', data);
            }
        };

        render() {            // Simply render the WrappedComponent with all props            return <WrappedComponent {...this.props} />;
        }
    }
    ...
}
withLinkAnalytics 함수는 WrappedComponent는 물론이고 WrappedComponent 컴포넌트 자체도 변경하지 않는다는 점에 유의해야 합니다. . 대신, 새로운 래핑된 구성 요소가 반환됩니다. 실제 사용법은 다음과 같습니다.
  • class Document extends React.Component {
        render() {        // ...
        }
    }
    
    export default withLinkAnalytics((props) => ({
        documentId: props.documentId
    }), Document);

    이런 방식으로 Document 구성 요소는 여전히 관심을 두어야 할 부분에만 관심을 기울이면 되며 withLinkAnalytics는 통계 논리를 재사용할 수 있는 기능을 제공합니다.

    고차 컴포넌트의 존재는 React의 타고난 구성 기능을 완벽하게 보여줍니다. React 커뮤니티에서는 일반적으로 React-redux, styled-Components, React-intl 등이 이 접근 방식을 채택했습니다. 재구성 클래스 라이브러리는 고차 구성 요소를 사용하고 이를 전달하여 "두뇌 확장" 작업을 수행한다는 점은 언급할 가치가 있습니다.

    React와 주변 커뮤니티의 등장으로 함수형 프로그래밍이 대중화되고 인기를 끌게 되었습니다. 분해와 구성에 대한 아이디어는 배울 가치가 있다고 생각합니다. 동시에 개발 및 설계에 대한 제안은 일반적인 상황에서는 구성 요소를 더 작고 단순한 구성 요소로 나누는 것을 주저하지 말고 견고성과 재사용으로 이어질 수 있다는 것입니다.

    관련 권장 사항:

    React 구성 요소 수명 주기의 인스턴스 분석

    React 구성 요소를 구축하는 가장 포괄적인 방법

    React 구성 요소를 최적화하는 스토어의 방법에 대한 자세한 설명

  • 위 내용은 React 구성 요소를 분해하는 몇 가지 고급 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

    성명:
    본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.