kullanma 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);
Bu, transclusion
Açısal olarak da bilinir .
children
React'te özel bir pervane ve bileşeninizin etiketlerinin içinde ne olduğunu içerecektir (işte <App name={name}/>
içeride Wrapper
, bu yüzdenchildren
children
Bir bileşen için benzersiz olan mutlaka kullanmanız gerekmediğini ve isterseniz normal sahne özelliklerini de kullanabileceğinizi veya sahne malzemeleri ile çocukları karıştırabileceğinizi unutmayın:
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);
Bu, birçok kullanım için basit ve iyidir ve çoğu tüketici uygulaması için bunu tavsiye ederim.
sahne yapmak
Oluşturma işlevlerini bir bileşene geçirmek mümkündür, bu desen genellikle çağrılır render prop
ve children
pervane genellikle bu geri aramayı sağlamak için kullanılır.
Bu örüntü gerçekten mizanpaj için tasarlanmamıştır. Sargı bileşeni genellikle bir durumu tutmak ve yönetmek ve bunu oluşturma işlevlerine enjekte etmek için kullanılır.
Karşı örnek:
const Counter = () => (
<State initial={0}>
{(val, set) => (
<div onClick={() => set(val + 1)}>
clicked {val} times
</div>
)}
</State>
);
Daha da süslü hale gelebilir ve hatta bir nesne bile sağlayabilirsiniz
<Promise promise={somePromise}>
{{
loading: () => <div>...</div>,
success: (data) => <div>{data.something}</div>,
error: (e) => <div>{e.message}</div>,
}}
</Promise>
Mutlaka kullanmanız gerekmediğini unutmayın children
, bu bir tat / API meselesidir.
<Promise
promise={somePromise}
renderLoading={() => <div>...</div>}
renderSuccess={(data) => <div>{data.something}</div>}
renderError={(e) => <div>{e.message}</div>}
/>
Bugün itibariyle birçok kütüphane render sahne (React bağlamı, React-motion, Apollo ...) kullanmaktadır, çünkü insanlar bu API'yi HOC'lardan daha kolay bulma eğilimindedir. tepki-powerplug basit render-prop bileşenleri bir koleksiyon. tepki-benimseme kompozisyon yapmanıza yardımcı olur.
Yüksek Dereceli Bileşenler (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);
Bir Üst Düzey Bileşeni / HOC genellikle bir bileşen alır ve yeni bir bileşen döndüren bir fonksiyondur.
Daha Yüksek Dereceli Bir Bileşen kullanmak children
veya kullanmaktan daha yüksek performans gösterebilir render props
, çünkü sargı işlemeyi bir adım öteye kısa devre yapma yeteneğine sahip olabilir shouldComponentUpdate
.
Burada kullanıyoruz PureComponent
. Uygulamayı yeniden oluştururken, WrappedApp
ad pervane zaman içinde değişmezse, sarıcı "sahne (aslında ad) eskisi gibi olduğu için işlemem gerekmez" diyebilir. İle children
yukarıda tabanlı bir çözüm, sarıcı olsa bile PureComponent
, çocukların eleman olasılıkla her zaman sarılmış bileşen saf olsa bile, yeniden verecek sarmalayıcı anlamına ebeveyn kılan her şey, yeniden çünkü böyle değildir. Bunu hafifletmeye ve zaman içinde sabit bir eleman sağlamaya yardımcı olabilecek bir babel eklentisi var children
.
Sonuç
Yüksek Sipariş Bileşenleri size daha iyi performans verebilir. Çok karmaşık değil ama ilk başta kesinlikle düşmanca görünüyor.
Bunu okuduktan sonra tüm kod tabanınızı HOC'a geçirmeyin. Uygulamanızın kritik yollarında, performans nedenleriyle çalışma zamanı sarmalayıcıları yerine HOC'ları kullanmak isteyebileceğinizi unutmayın, özellikle de aynı sarmalayıcı birçok kez kullanılıyorsa, onu bir HOC yapmayı düşünmeye değer.
Redux ilk önce bir çalışma zamanı sarıcısı kullandı <Connect>
ve daha sonra connect(options)(Comp)
performans nedenleriyle bir HOC'ye geçti (varsayılan olarak sarıcı saftır ve kullanılır shouldComponentUpdate
). Bu, bu cevapta vurgulamak istediğim şeyin mükemmel bir örneğidir.
Bir bileşenin bir render-prop API'sı varsa, bunun üzerine bir HOC oluşturmak genellikle kolaydır, bu nedenle bir lib yazarsanız, önce bir render prop API'sı yazmalı ve sonunda bir HOC sürümü sunmalısınız. Apollo'nun <Query>
render-prop bileşeni ve graphql
HOC bunu kullanarak yaptığı şey budur.
Şahsen, her ikisini de kullanıyorum, ancak şüpheye düştüğümde HOC'ları tercih ederim çünkü:
compose(hoc1,hoc2)(Comp)
Sahne oluşturmakla karşılaştırıldığında onları ( ) oluşturmak daha deyimsel
- Bana daha iyi performanslar verebilir
- Bu tarz bir programa aşinayım
En sevdiğim araçların HOC sürümlerini kullanmaktan / oluşturmaktan çekinmeyin:
- En Tepki
Context.Consumer
comp
- yersiz en
Subscribe
- render prop
graphql
yerine Apollo'nun HOC'sini kullanmaQuery
Bence, bazen sahne kodu daha okunabilir, bazen daha az yapmak ... Ben sahip olduğum kısıtlamalara göre en pragmatik çözümü kullanmaya çalışıyorum. Bazen okunabilirlik performanslardan daha önemlidir, bazen değil. Akıllıca seçin ve 2018'in her şeyi render-props'lara dönüştürme eğilimini takip etmeyin.