Как передать компонент react в другой компонент react, чтобы превзойти содержимое первого компонента?

есть ли способ передать один компонент в другой компонент react? Я хочу создать компонент модели react и передать другой компонент react, чтобы трансцендировать это содержимое.

Edit: вот код reactJS, иллюстрирующий то, что я пытаюсь сделать. http://codepen.io/aallbrig/pen/bEhjo

HTML-код

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

ReactJS

/**@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'));

6 ответов


Примечание я предоставил более глубокий ответ здесь

во время выполнения фантик:

это самый идиоматический способ.

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 является "специальной опорой" в React, а приведенный выше пример является синтаксическим сахаром и (почти) эквивалентен <Wrapper children={<App/>}/>


инициализация wrapper / HOC

можно использовать Компонент Высшего Порядка (HOC). Они были добавлены к официальный док!--9--> недавно.

// 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 Redux раньше был оболочкой времени выполнения, но был изменен на HOC, потому что он позволяет чтобы избежать бесполезных рендеров, если вы используете (по умолчанию)

вы никогда не должны вызывать HOC на этапе рендеринга, потому что создание компонентов React может быть дорогостоящим. Вы должны скорее вызвать эти обертки при инициализации.


обратите внимание, что при использовании функциональных компонентов, как указано выше, специальная версия не обеспечивает никакой полезной оптимизации, поскольку функциональные компоненты без состояния не реализуют shouldComponentUpdate

больше объяснения здесь:https://stackoverflow.com/a/31564812/82609


можно использовать this.props.children оказывать посильную детей компонент содержит:

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

var App = React.createClass({
    render: function() {
        return <Wrap><h1>Hello word</h1></Wrap>;
    }
});

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} />

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);

вы можете передать компонент через. реквизит и рендеринг с интерполяцией.

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

вы бы тогда пройти в prop под названием child, который будет компонентом React.


Я предпочитаю использовать 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>