반응 성분을 다른 반응 성분으로 전달하여 첫 번째 성분의 내용을 포함시키는 방법은 무엇입니까?


216

한 구성 요소를 다른 반응 구성 요소로 전달하는 방법이 있습니까? 모델 반응 구성 요소를 만들고 다른 반응 구성 요소를 전달하여 해당 내용을 변환하고 싶습니다.

편집 : 여기 내가하려는 일을 보여주는 reactJS 코드 펜이 있습니다. http://codepen.io/aallbrig/pen/bEhjo

HTML

<div id="my-component">
    <p>Hi!</p>
</div>

반응 JS

/**@jsx React.DOM*/

var BasicTransclusion = React.createClass({
  render: function() {
    // Below 'Added title' should be the child content of <p>Hi!</p>
    return (
      <div>
        <p> Added title </p>
        {this.props.children}
      </div>
    )
  }
});

React.renderComponent(BasicTransclusion(), document.getElementById('my-component'));

답변:


198

this.props.children구성 요소에 포함 된 모든 자식을 렌더링 하는 데 사용할 수 있습니다 .

const Wrap = ({ children }) => <div>{children}</div>

export default () => <Wrap><h1>Hello word</h1></Wrap>

4
이 답변을 사용합니다. this.props.children구성 요소 API의 일부이며이 방식으로 사용될 것으로 예상됩니다. React 팀의 예제는 소품전송 하거나 단일 아동 에 대해 이야기 할 때와 같이이 기술을 사용합니다 .
Ross Allen

아래 내 의견에서 : 소품으로 전달하면 이름을 지정하고 propTypes를 사용하여 유형을 확인할 수도 있습니다.
returneax

1
@AndrewAllbright : 귀하의 예는 자녀를 전달하지 않았습니다. 이것은 작동합니다 : codepen.io/ssorallen/pen/Dyjmk
Ross Allen

그리고 만약 당신이 아이들의 DOM 노드를 원한다면 : stackoverflow.com/questions/29568721/…
ericsoco

124

여기에 더 자세한 답변을 제공했습니다.

런타임 래퍼 :

가장 관용적 인 방법입니다.

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

const App = () => <div>Hello</div>;

const WrappedApp = () => (
  <Wrapper>
    <App/>
  </Wrapper>
);

참고 children"특별한 소품"반작용에, 위의 예제는 문법 설탕과에 (거의) 동일합니다<Wrapper children={<App/>}/>


초기화 래퍼 / HOC

HOC ( Higher Order Component)를 사용할 수 있습니다 . 최근에 공식 문서 에 추가되었습니다 .

// Signature may look fancy but it's just 
// a function that takes a component and returns a new component
const wrapHOC = (WrappedComponent) => (props) => (
  <div>
    <div>header</div>
    <div><WrappedComponent {...props}/></div>
    <div>footer</div>
  </div>
)

const App = () => <div>Hello</div>;

const WrappedApp = wrapHOC(App);

래퍼 구성 요소는 shouldComponentUpdate를 사용하여 렌더링을 한 단계 앞당길 수 있기 때문에 성능이 약간 저하 될 수 있습니다. 컴포넌트가 PureComponent를 확장하더라도

이 공지 사항 connect돌아 오는의 런타임 래퍼로 사용하지만 쓸모 방지 할 수있게 때문에 HOC로 변경 재 - 렌더링 당신이 사용하는 경우 pure(기본적으로 true입니다) 옵션을

React 컴포넌트를 작성하는 데 많은 비용이들 수 있으므로 렌더링 단계에서 HOC를 호출하면 안됩니다. 초기화시이 랩퍼를 호출해야합니다.


위와 같은 기능적 구성 요소를 사용할 때 HOC 버전은 상태 비 저장 기능성 구성 요소가 구현되지 않기 때문에 유용한 최적화를 제공하지 않습니다. shouldComponentUpdate

자세한 설명은 여기 : https://stackoverflow.com/a/31564812/82609


29
const ParentComponent = (props) => {
  return(
    {props.childComponent}
    //...additional JSX...
  )
}

//import component
import MyComponent from //...where ever

//place in var
const myComponent = <MyComponent />

//pass as prop
<ParentComponent childComponent={myComponent} />

이것이 맞다면 이것이 옳았을 것입니다 ... React 15.x는 다중 노드 컴포넌트를 반환 할 수 없습니다. React 16 (일명 React Fiber)은 여러 노드를 허용합니다. 코드 샘플의 수정 사항은 다음과 같습니다. const ParentComponent = (props) => ({props.childComponent}); // ... 어디에서나 myComponent 가져 오기 const myComponent = <MyComponent /> // 소품으로 전달 <ParentComponent childComponent = {myComponent} />
Andrew Allbright

13

Facebook은 상태 비 저장 구성 요소 사용을 권장합니다. 출처 : https://facebook.github.io/react/docs/reusable-components.html

이상적인 세계에서 대부분의 구성 요소는 상태 비 저장 기능이 될 것입니다. 앞으로는 불필요한 검사 및 메모리 할당을 피함으로써 이러한 구성 요소에 맞게 성능을 최적화 할 수 있기 때문입니다. 가능하면 권장되는 패턴입니다.

function Label(props){
    return <span>{props.label}</span>;
}

function Hello(props){
    return <div>{props.label}{props.name}</div>;
}

var hello = Hello({name:"Joe", label:Label({label:"I am "})});

ReactDOM.render(hello,mountNode);

13

일반 소품으로 전달할 수 있습니다. foo={<ComponentOne />}

예를 들면 다음과 같습니다.

const ComponentOne = () => <div>Hello world!</div>
const ComponentTwo = () => (
  <div>
    <div>Hola el mundo!</div>
    <ComponentThree foo={<ComponentOne />} />
  </div>
)
const ComponentThree = ({ foo }) => <div>{foo}</div>

9

React 내장 API를 선호합니다.

import React, {cloneElement, Component} from "react";
import PropTypes from "prop-types";

export class Test extends Component {
  render() {
    const {children, wrapper} = this.props;
    return (
      cloneElement(wrapper, {
        ...wrapper.props,
        children
      })
    );
  }
}

Test.propTypes = {
  wrapper: PropTypes.element,
  // ... other props
};

Test.defaultProps = {
  wrapper: <div/>,
  // ... other props
};

그런 다음 래퍼 div를 원하는 것으로 바꿀 수 있습니다.

<Test wrapper={<span className="LOL"/>}>
  <div>child1</div>
  <div>child2</div>
</Test> 

5

통해 구성 요소를 전달할 수 있습니다. 소품을 보간으로 렌더링합니다.

var DivWrapper = React.createClass({
    render: function() {
        return <div>{ this.props.child }</div>;
    }
});

그런 다음 prop이라는 을 전달 child하면 React 컴포넌트가됩니다.


1
이로 인해 자식이 아닌 속성을 통해 구성 요소를 전달하게됩니다. this.props.children다른 답변에서 제안한대로 사용 하면 자녀를 attrs 대신 자녀로 쓸 수 있습니다.
Ross Allen

1
@ ssorallen 당신은 왜 어떤 방법으로 더 나은지 말하지 않았습니다 ... 소품으로 전달하여 이름을 부여하고 propTypes를 사용하여 검사를 입력 할 수도 있습니다.
returneax

1
JSX에서 사용하는 모든 요소는 구성 요소 일뿐입니다. 그들이이 접근 방식을 사용했다면 짧은 예제조차 쓸 수 없을 것입니다. 될 것 <div child={this.props.child />입니다.
Ross Allen

1
(JSX가로인가요?) 자바 스크립트 버전을 확인 jsfiddle.net/ssorallen/kvrxcqv8/2을 . React.DOM.div모든 핵심 구성 요소와 마찬가지로 children배열을 사용합니다 . Hello구성 요소 에서 어떻게 사용되는지 살펴보십시오 . 이미 여러 자식을 사용하고 있습니다.
Ross Allen

20
채팅에서 토론을 계속하면 단점은 향후 독자를 위해 보관되지 않는다는 것입니다.
ultrafez

3

게임에 늦었지만 구성 요소를 소품으로 제공하여 구성 요소를 재정의하는 강력한 HOC 패턴이 있습니다. 간단하고 우아합니다.

MyComponent가상의 A구성 요소를 렌더링 하지만 A이 예제 에서 a B를 감싸고 "!"를 추가 하는 사용자 정의 대체를 허용하려고 한다고 가정하십시오 . 텍스트 소품에 :A<div>...</div>

import A from 'fictional-tooltip';

const MyComponent = props => (
  <props.A text="World">Hello</props.A>
);
MyComponent.defaultProps = { A };

const B = props => (
  <div><A {...props} text={props.text + '!'}></div>
);

ReactDOM.render(<MyComponent A={B}/>);

1

실제로, 귀하의 질문은 고차 컴포넌트 (HOC)를 작성하는 방법입니다. HOC 사용의 주요 목표는 복사 붙여 넣기를 방지하는 것입니다. HOC를 순전히 기능적인 구성 요소 또는 클래스로 작성할 수 있습니다. 여기 예가 있습니다.

    class Child extends Component {
    render() {
        return (
            <div>
                Child
            </div>
        );
    }
}

부모 컴포넌트를 클래스 기반 컴포넌트로 작성하려면 다음을 수행하십시오.

    class Parent extends Component {
    render() {
        return (
            <div>
                {this.props.children}
            </div>
        );
    }
}

부모를 기능적 구성 요소로 작성하려면 다음을 수행하십시오.

    const Parent=props=>{
    return(
        <div>
            {props.children}
        </div>
    )
}

0

다음은 상위 List 반응 구성 요소 및 whos props에 반응 요소를 포함 하는 예입니다 . 이 경우 단 하나의 링크 반응 구성 요소 만 전달됩니다 (돔 렌더링에서 볼 수 있음).

class Link extends React.Component {
  constructor(props){
    super(props);
  }
  render(){
    return (
      <div>
        <p>{this.props.name}</p>
      </div>
     );
  }
}
class List extends React.Component {
  render(){
   return(
    <div>
       {this.props.element}
       {this.props.element}
    </div>
   );
  }
}

ReactDOM.render(
  <List element = {<Link name = "working"/>}/>,
  document.getElementById('root')
);

0

예, 소품을 사용하여 구성 요소의 데이터를 소품과 같은 객체로 전달할 수 있으며 구성 요소 내부에서 다른 구성 요소를 가져 와서 prpps 데이터와 동적으로 바인딩 할 수 있습니다. 반응 성분에 대해서 더 읽어보세요.


1
당신은 당신이 게시 한 링크에서 일부 코드를 정교하게 할 수 있습니까
Nelles
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.