IT이야기

반응.js: 한 구성 요소를 다른 구성 요소로 포장

cyworld 2022. 3. 14. 21:33
반응형

반응.js: 한 구성 요소를 다른 구성 요소로 포장

많은 템플릿 언어에는 "슬롯" 또는 "수혜" 문장이 있는데, 이를 통해 하나의 템플릿을 다른 템플릿 안에 감싸기 위해 일종의 통제의 역전을 할 수 있다.

각도에는 "변환" 옵션이 있다.

레일즈는 항복선언이 있다.리액션 js가 항복문을 가지고 있다면 다음과 같이 보일 것이다.

var Wrapper = React.createClass({
  render: function() {
    return (
      <div className="wrapper">
        before
          <yield/>
        after
      </div>
    );
  }
});

var Main = React.createClass({
  render: function() {
    return (
      <Wrapper><h1>content</h1></Wrapper>
    );
  }
});

원하는 출력:

<div class="wrapper">
  before
    <h1>content</h1>
  after
</div>

아아, 리액트.js는 그런 것이 없다.<yield/>동일한 출력을 얻기 위해 Wrapper 구성 요소를 정의하려면 어떻게 해야 하는가?

시도:

var Wrapper = React.createClass({
  render: function() {
    return (
      <div className="wrapper">
        before
          {this.props.children}
        after
      </div>
    );
  }
});

여러 구성 요소: 자세한 내용을 보려면 문서에 있는 Children과 Type of the Children을 참조하십시오.

사용.children

const Wrapper = ({children}) => (
  <div>
    <div>header</div>
    <div>{children}</div>
    <div>footer</div>
  </div>
);

const App = ({name}) => <div>Hello {name}</div>;

const WrappedApp = ({name}) => (
  <Wrapper>
    <App name={name}/>
  </Wrapper>
);

render(<WrappedApp name="toto"/>,node);

이것은 또한 로 알려져 있다.transclusion각도에서.

children반응의 특수 소품이며 구성 요소의 태그 안에 있는 것을 포함함(여기)<App name={name}/>안에 있다Wrapper, 그래서 그것은 이다.children

반드시 사용할 필요는 없다는 점에 유의하십시오.children구성 요소 전용이며, 원하는 경우 일반 소품도 사용하거나 소품과 어린이를 혼합하여 사용할 수 있다.

const AppLayout = ({header,footer,children}) => (
  <div className="app">
    <div className="header">{header}</div>
    <div className="body">{children}</div>
    <div className="footer">{footer}</div>
  </div>
);

const appElement = (
  <AppLayout 
    header={<div>header</div>}
    footer={<div>footer</div>}
  >
    <div>body</div>
  </AppLayout>
);

render(appElement,node);

이것은 많은 이용자들에게 간단하고 괜찮으며, 나는 대부분의 소비자 앱에 이것을 추천하고 싶다.


소품을 제작하다

렌더 함수를 구성요소에 전달할 수 있으며, 이 패턴을 일반적으로 , 그리고children소포는 콜백을 제공하기 위해 종종 사용된다.

이 패턴은 실제로 레이아웃을 위한 것이 아니다.래퍼 구성요소는 일반적으로 일부 상태를 유지 및 관리하고 렌더 기능에 주입하는 데 사용된다.

카운터 예:

const Counter = () => (
  <State initial={0}>
    {(val, set) => (
      <div onClick={() => set(val + 1)}>  
        clicked {val} times
      </div>
    )}
  </State>
); 

당신은 훨씬 더 멋지고 심지어 물건을 제공할 수 있다.

<Promise promise={somePromise}>
  {{
    loading: () => <div>...</div>,
    success: (data) => <div>{data.something}</div>,
    error: (e) => <div>{e.message}</div>,
  }}
</Promise>

반드시 사용할 필요는 없음children, 그것은 맛/API의 문제다.

<Promise 
  promise={somePromise}
  renderLoading={() => <div>...</div>}
  renderSuccess={(data) => <div>{data.something}</div>}
  renderError={(e) => <div>{e.message}</div>}
/>

오늘날, 많은 도서관이 렌더 소품(Ract context, React-motion, Apolo...)을 사용하고 있는데, 사람들이 이 API를 HOR의 것보다 더 쉽게 발견하는 경향이 있기 때문이다. 리액션 파워 플러그는 단순한 렌더 제안 구성요소의 집합이다.react-react-reason은 당신이 작곡을 하는 것을 돕는다.


고차 부품(HOC)

const wrapHOC = (WrappedComponent) => {
  class Wrapper extends React.PureComponent {
    render() {
      return (
        <div>
          <div>header</div>
          <div><WrappedComponent {...this.props}/></div>
          <div>footer</div>
        </div>
      );
    }  
  }
  return Wrapper;
}

const App = ({name}) => <div>Hello {name}</div>;

const WrappedApp = wrapHOC(App);

render(<WrappedApp name="toto"/>,node);

고차 구성요소/HOR는 일반적으로 구성요소를 가져다가 새로운 구성요소를 반환하는 기능이다.

고차 구성 요소를 사용하는 것이 사용보다 더 효과적일 수 있음children또는render props래퍼는 다음 단계로 한 단계 앞서 렌더링을 단락시킬 수 있기 때문에shouldComponentUpdate.

여기 우리가 사용하고 있다.PureComponent. 앱을 다시 렌더링할 때, 만약WrappedApp이름 받침은 시간이 지남에 따라 변하지 않으며, 포장지에는 "소품(사실상 이름)이 이전과 같기 때문에 렌더링할 필요가 없다"고 말하는 기능이 있다.With thechildren포장지가 위와 같더라도 위와 같은 솔루션PureComponent부모가 렌더링할 때마다 자식 요소가 재생성되기 때문에 포장된 성분이 순수하더라도 포장지가 항상 다시 재생성될 가능성이 높기 때문에 그렇지 않다.이를 완화하고 상수를 보장할 수 있는 Babel 플러그인이 있다.children시간 경과에 따른 요소


결론

고차 부품은 더 나은 성능을 제공할 수 있다.그것은 그렇게 복잡하지는 않지만 처음에는 확실히 불친절해 보인다.

이 내용을 읽은 후에는 코드베이스를 HOK로 마이그레이션하지 마십시오.앱의 중요한 경로에서는 성능상의 이유로 런타임 래퍼 대신 HORK를 사용할 수 있다는 점을 기억하십시오. 특히 동일한 래퍼를 많이 사용하는 경우에는 HORK로 만드는 것을 고려해 보십시오.

처음에 런타임 래퍼에 사용된 Redex<Connect>에 HOKRO로 했다.connect(options)(Comp)성능상의 이유(기본적으로 래퍼는 순수하며 사용됨)shouldComponentUpdate이것은 내가 이 대답에서 강조하고자 했던 것을 보여주는 완벽한 삽화다.

구성요소에 렌더 프로포즈 API가 있는 경우, 일반적으로 그 위에 HORK를 만드는 것이 쉬우므로, lib 작성자인 경우 렌더 프로펠러 API를 먼저 작성하고, 최종적으로 HORK 버전을 제공해야 한다.이것이 아폴로가 가지고 있는 것이다.<Query>렌더 프로포즈 구성 요소 및graphqlHORK 사용.

개인적으로 나는 두 가지를 모두 사용하지만, 의심스러울 때는 다음과 같은 이유로 HORK를 선호한다.

  • 그것들을 구성하는 것이 더 관용적이다.compose(hoc1,hoc2)(Comp)소품 렌더링과 비교
  • 그것은 나에게 더 나은 공연을 줄 수 있다.
  • 나는 이런 프로그래밍 스타일에 익숙하다.

내가 좋아하는 도구의 HORK 버전 사용/작성:

  • 리액션스Context.Consumer콤파스
  • 언트레이티드스Subscribe
  • 사용.graphql대신에 아폴로 호크 오브 아폴로Query소품을 내다.

내 생각에는, 때때로 소품을 렌더링하면 코드를 더 잘 읽을 수 있고, 때로는 덜 읽을 수 있다...나는 내가 가진 제약조건에 따라 가장 실용적인 해결책을 사용하려고 노력한다.때로는 가독성이 공연보다 더 중요하고 때로는 그렇지 않다.현명하게 선택하고 모든 것을 렌더-프로포즈로 전환하는 2018년 트렌드를 따라가지 마십시오.

소피의 대답 외에도, 나는 다음과 같은 일을 하면서 아동 구성품 타입을 보내는 데도 쓸모가 있다는 것을 알게 되었다.

var ListView = React.createClass({
    render: function() {
        var items = this.props.data.map(function(item) {
            return this.props.delegate({data:item});
        }.bind(this));
        return <ul>{items}</ul>;
    }
});

var ItemDelegate = React.createClass({
    render: function() {
        return <li>{this.props.data}</li>
    }
});

var Wrapper = React.createClass({    
    render: function() {
        return <ListView delegate={ItemDelegate} data={someListOfData} />
    }
});

참조URL: https://stackoverflow.com/questions/20851533/react-js-wrapping-one-component-into-another

반응형