İlk bileşenin içeriğini aşmak için bir reaksiyon bileşenini başka bir reaksiyon bileşenine nasıl aktarabilirim?


216

Bir bileşeni başka bir reaksiyon bileşenine geçirmenin bir yolu var mı? Bir model tepki bileşeni oluşturmak ve bu içeriği dönüştürmek için başka bir tepki bileşenini geçmek istiyorum.

Düzenleme: İşte ne yapmaya çalışıyorum gösteren bir reaktifJS kodpen. 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'));

Yanıtlar:


198

this.props.childrenBileşenin içerdiği alt öğeleri oluşturmak için kullanabilirsiniz :

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

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

4
Bu cevabı kullanırdım. this.props.childrenbileşen API'sının bir parçasıdır ve bu şekilde kullanılması beklenir. React ekibinin örnekleri, sahne aktarımında ve tek bir çocuktan bahsederken olduğu gibi bu tekniği kullanır .
Ross Allen

Aşağıdaki yorumumdan: Bir pervane olarak ileterek, bir ad bile verebilir ve çek yazmak için propTypes kullanabilirsiniz.
returneax

1
@AndrewAllbright: Örneğiniz herhangi bir çocuğu geçmiyordu. Bu çalışıyor: codepen.io/ssorallen/pen/Dyjmk
Ross Allen

Ve sonra çocukların DOM Düğümlerini almak istiyorsanız: stackoverflow.com/questions/29568721/…
ericsoco

124

Not Burada daha ayrıntılı bir cevap verdim

Çalışma zamanı sarmalayıcısı:

Bu en deyimsel yol.

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

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

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

Not children"özel bir pervane" tepki olarak ve yukarıda örnek sözdizimsel şeker ve (neredeyse) eşdeğerdir<Wrapper children={<App/>}/>


Başlatma sargısı / HOC

Bir Yüksek Sipariş Bileşeni (HOC) kullanabilirsiniz. Son zamanlarda resmi dokümana eklendi .

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

Bu, (daha az) daha iyi performanslara yol açabilir, çünkü sarma bileşeni, renderComponentUpdate ile bir adım öteye renderleme işlemini kısa devre yapabilirken, çalışma zamanı sarmalayıcısı durumunda, çocuk pervane her zaman farklı bir ReactElement olabilir ve yeniden oluşturuculara neden olabilir bileşenleriniz PureComponent'i uzatsa bile.

connectRedux'un eskiden çalışma zamanı sarıcısı olduğuna dikkat edin, ancak pureseçeneği kullanırsanız işe yaramaz yeniden oluşturma işlemlerinden kaçınmasına izin verdiği için bir HOC olarak değiştirildiğine dikkat edin (varsayılan olarak doğrudur)

React bileşenleri oluşturmak pahalı olabileceğinden, oluşturma aşamasında asla HOC çağırmamalısınız. Başlangıçta bu paketleyicileri çağırmayı tercih etmelisiniz.


Yukarıdaki gibi fonksiyonel bileşenler kullanıldığında, vatansız fonksiyonel bileşenler uygulanmadığı için HOC sürümünün herhangi bir yararlı optimizasyon sağlamadığını unutmayın. shouldComponentUpdate

Burada daha fazla açıklama: 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} />

Bu doğru olsaydı ... React 15.x çok düğümlü bir bileşen döndürmenize izin vermez. React 16 (diğer adıyla React Fiber) birden fazla düğüme izin verecektir. Kod örneğiniz için düzeltme: const ParentComponent = (props) => ({props.childComponent}); İthalat MyComponent //...where zamankinden const MyComponent = <MyComponent /> // pervane olarak geçmektedir <ParentComponent childComponent = {MyComponent} />
Andrew Allbright

13

Facebook durumsuz bileşen kullanımını önermektedir Kaynak: https://facebook.github.io/react/docs/reusable-components.html

İdeal bir dünyada, bileşenlerinizin çoğu vatansız işlevler olacaktır, çünkü gelecekte gereksiz denetimlerden ve bellek ayırmalardan kaçınarak bu bileşenlere özgü performans optimizasyonları da yapabileceğiz. Bu, mümkünse önerilen kalıptır.

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

Normal bir pervane olarak iletebilirsiniz: foo={<ComponentOne />}

Örneğin:

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 yerleşik API kullanmayı tercih ederim:

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

daha sonra sarmalayıcı div'ı istediğiniz şeyle değiştirebilirsiniz:

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

5

Bir bileşeni üzerinden iletebilirsiniz. sahne ve enterpolasyon ile render.

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

Daha sonra içinde geçerdi propdenilen childbir bileşen tepki olacağını.


1
Bu, bileşenleri çocuk olarak değil özniteliklerle geçirmeye yol açacaktır. this.props.childrenBaşka bir cevapta önerildiği gibi kullanırsanız , çocukları attr yerine çocuk olarak yazabilirsiniz.
Ross Allen

1
@ssorallen, neden herhangi bir şekilde daha iyi olduğunu söylemediniz ... Bir pervane olarak geçerek bile bir isim verebilir ve çek yazmak için propTypes kullanabilirsiniz.
returneax

1
JSX'te kullandığınız her öğe yalnızca bir bileşendir. Eğer bu yaklaşımı kullanırlarsa, kısa örneğinizi bile yazamazsınız. Olurdu <div child={this.props.child />.
Ross Allen

1
JavaScript sürümüne göz atın (JSX'in dönüştürdüğü şey): jsfiddle.net/ssorallen/kvrxcqv8/2 . React.DOM.div, tüm temel bileşenler gibi childrendiziyi kullanır . HelloBileşeninizde nasıl kullanıldığına bakın, zaten birden fazla çocuk kullanıyor.
Ross Allen

20
Sohbette tartışmaya devam etmenin dezavantajı, gelecekteki okuyucular için arşivlenmemeleri.
15'de ultrafez

3

Oyunun sonlarına doğru, ama burada bir bileşeni prop olarak sağlayarak geçersiz kılmak için güçlü bir HOC deseni. Basit ve zarif.

Varsayalım MyComponentkurgusal hale Abileşeni ancak özel bir geçersiz kılma için izin vermek istediğiniz Abu örnekte, Bsarar, Abir de <div>...</div>hem de ekler "!" metin pervanesine:

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

Aslında, sorunuz nasıl bir Yüksek Sipariş Bileşeni (HOC) yazacağınızdır. HOC'yi kullanmanın temel amacı kopya yapışmasını önlemektir. HOC'nizi tamamen işlevsel bir bileşen olarak veya burada bir sınıf olarak yazabilirsiniz burada bir örnek:

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

Üst bileşeninizi sınıf tabanlı bileşen olarak yazmak istiyorsanız:

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

Ebeveyninizi fonksiyonel bir bileşen olarak yazmak istiyorsanız:

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

0

Burada bir üst Liste reaksiyon bileşenine bir örnek verilmiştir ve bu aksesuarlar bir reaksiyon elementi içerir. Bu durumda, yalnızca tek bir Link tepki bileşeni geçirilir (dom render'da görüldüğü gibi).

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.