This.props.children yerine React.cloneElement'i ne zaman kullanmalıyım?


118

Hala React'te bir noob'um ve internetteki birçok örnekte, kafa karıştırıcı bulduğum çocuk öğeleri oluşturmada bu çeşitliliği görüyorum. Normalde şunu görüyorum:

class Users extends React.Component {
  render() {
    return (
      <div>
        <h2>Users</h2>
        {this.props.children}
      </div>
    )
  }
}

Ama sonra şöyle bir örnek görüyorum:

<ReactCSSTransitionGroup
     component="div"
     transitionName="example"
     transitionEnterTimeout={500}
     transitionLeaveTimeout={500}
     >
     {React.cloneElement(this.props.children, {
       key: this.props.location.pathname
      })}
</ReactCSSTransitionGroup>

Şimdi api'yi anlıyorum, ancak dokümanlar onu ne zaman kullanmam gerektiğini tam olarak açıklamıyor.

Peki biri diğerinin yapamadığı ne yapar? Birisi bunu bana daha iyi örneklerle açıklayabilir mi?


3
youtube.com/watch?v=hEGg-3pIHlE bu adam cloneElement'i nasıl kullandığını gösteriyor. Bazı örnekler için buna bir göz atın
iurii

Yanıtlar:


69

Düzenle:

Bunun yerine daha iyi bir açıklama olan Vennesa'nın cevabına bakın .

Orijinal:

Her şeyden önce, React.cloneElementörnek yalnızca çocuğunuz tek bir React öğesi ise işe yarar.

Neredeyse her şey {this.props.children}sizin istediğinizdir. Klonlama, bir üst öğenin bir öğe gönderdiği ve alt bileşenin o öğedeki bazı özellikleri değiştirmesi veya gerçek DOM öğesine erişmek için ref gibi şeyler eklemesi gereken bazı daha gelişmiş senaryolarda kullanışlıdır.

Yukarıdaki örnekte, çocuğa bileşen için anahtar gereksinimi bilmediğini veren ebeveyn, bu nedenle verildiği öğenin bir kopyasını oluşturur ve nesnedeki bazı benzersiz tanımlayıcılara dayalı bir anahtar ekler. Tuşun ne işe yaradığı hakkında daha fazla bilgi için: https://facebook.github.io/react/docs/multiple-components.html


183

props.childrengerçek çocuklar değil; Öyle descriptorçocukların. Yani aslında değiştirecek hiçbir şeyiniz yok; herhangi bir sahne donanımını değiştiremez veya herhangi bir işlevi düzenleyemezsiniz; sadece yapabilirsin read from it. Herhangi bir değişiklik yapmak gerekirse oluşturmak zorunda new elementskullanarak React.CloneElement.

https://egghead.io/lessons/react-use-react-cloneelement-to-extend-functionality-of-children-components

Bir örnek:

gibi bir bileşenin ana oluşturma işlevi App.js:

render() {   
    return(
            <Paragraph>
              <Sentence>First</Sentence>
              <Sentence>Second</Sentence>
              <Sentence>Third</Sentence>
            </Paragraph>   
    ) 
}

şimdi diyelim ki onClickher çocuğa bir eklemeniz gerekiyor Paragraph; yani Paragraph.jssende yapabilirsin:

render() {
        return (
          <div>
          {React.Children.map(this.props.children, child => {
            return React.cloneElement(child, {
              onClick: this.props.onClick })   
         })}
         </div>
       ) 
}

o zaman bunu basitçe yapabilirsiniz:

render() {   
  return(
        <Paragraph onClick={this.onClick}>
          <Sentence>First</Sentence>
          <Sentence>Second</Sentence>
          <Sentence>Third</Sentence>
        </Paragraph>   
   ) 
}

Not:React.Children.map işlevi yalnızca göreceksiniz top levelbu o unsurlar hale şeylerin herhangi görmez, elemanlar; çocuklara doğrudan sahne sağladığınız anlamına gelir (burada <Sentence />öğeler). Desteğin daha ileri aktarılmasına ihtiyacınız varsa, diyelim ki pervaneyi kullanmak isteyen öğelerden <div></div>birinin içinde olacaksınız, o zaman bunu yapmak için kullanabilirsiniz. Make sağlayıcı ve tüketici olarak unsurları.<Sentence />onClickContext APIParagraphSentence


11
Bu, gerçek dünya örneğiyle net bir cevaptır. Daha fazla oylamaya ihtiyacı var.
SeaWarrior404

1
@ SeaWarrior404 ile aynı fikirdeyim - OP'nin tek bir çocuk yerine bir koleksiyon üzerinde yinelemeye çalıştığını tahmin ediyorum çünkü kullanıcı arayüzünde başlık olarak "Kullanıcılar" / çoğul var. @Vennesa React.Children.mapile birlikte kullanmak React.cloneElementçok güçlü
jakeforaker

23

Aslında, React.cloneElementkesinlikle ile ilişkili değildir this.props.children.

PropTypes.elementProps eklemek / geçersiz kılmak için react elemanlarını ( ) klonlamanız gerektiğinde , ebeveynin bu bileşen iç bileşenleri hakkında bilgi sahibi olmasını istemediğinizde (örn., Olay işleyicileri ekleme veya atama key/ reföznitelikler) kullanışlıdır .

Ayrıca tepkime elemanları değişmezdir .

React.cloneElement (element, [props], [... children]) hemen hemen eşdeğerdir: <element.type {...element.props} {...props}>{children}</element.type>


Bununla birlikte, React'teki childrenprop, özellikle kapsama (diğer adıyla kompozisyon ), React.ChildrenAPI ile eşleştirme ve React.cloneElementprops.children kullanan bileşen için kullanılır. nerede kullanılırsa kullanılsın, React Router <switch/>veya bileşik bileşen <select/>bazı harika örneklerdir.

Bahsetmeye değer son bir şey de react unsurlarının props.children ile sınırlı olmamasıdır.

function SplitPane(props) {
  return (
    <div className="SplitPane">
      <div className="SplitPane-left">
        {props.left}
      </div>
      <div className="SplitPane-right">
        {props.right}
      </div>
    </div>
  );
}

function App() {
  return (
    <SplitPane
      left={
        <Contacts />
      }
      right={
        <Chat />
      } />
  );
}

Onlar mantıklı ne olursa olsun sahne olabilir, anahtar, bileşen için iyi bir sözleşme tanımlamak bu yüzden bunun tüketicilerin o kullanıyor olursa olsun, ister yatan uygulama ayrıntılarını ayrılabilen bu React.Children, React.cloneElementhatta React.createContext.

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.