[英]How to pass React Component prop to child function using {children}?
我是 React 的新手,所以這可能很明顯,但我不能通過道具傳遞給從其父級創建組件的 function。
我可以將道具傳遞給子組件,但同樣不適用於函數。
我有<Subscription>
我可以通過 arguments 像這樣,從它的父post
:
<Subscription auth={auth} stripeAmount={post.amount} stripePlanId={post.planid}/>
這將創建一個 Stripe 訂閱。 我想限制訂閱以訂閱我通過以下方式訂閱的stripePlanId
:
class Subscription extends React.Component {
// https://stripe.com/docs/checkout#integration-custom
componentDidMount() {
this.stripeCheckout = window.StripeCheckout.configure({
...etc...
email: this.props.auth.email,
})
}
newSubscription = () => {
var stripePlanId = this.props.stripePlanId;
this.stripeCheckout.open({
amount: this.props.stripeAmount, // in cents
description: this.props.stripePlanId,
token: function(token){
createSubscription(token, stripePlanId)
}
})
}
..etc..
這很好用。 But now to pass through the stripePlanId I can't find out how to pass the stripePlanId
through since it renders via a function - this {children}
argument seems to only pass in the function, and attempting to add arguments causes errors that they are not它期望對傳遞的 arguments 起作用的函數:
const FireflySubscription = ({children}) => (
<FirebaseAuth>
{ ({isLoading, error, auth}) => {
if (error || isLoading || !auth) {
//it pushes these arguments to the parent function
return children({
error,
isLoading,
subscription: null,
})
}
// the issue - how to populate this?
const stripePlanId = ""
// when working this should return the subscription for only this planId
if (stripePlanId) {
return <FirestoreCollection
path="subscriptions"
filter={[['createdBy', '==', auth.uid], ['stripePlanId','==', stripePlanId]]}
>
{ ({error, isLoading, data}) => {
return children({
error,
isLoading,
subscription: data.length > 0 ? data : null,
})
}}
</FirestoreCollection>
}
return <FirestoreCollection
path="subscriptions"
filter={['createdBy', '==', auth.uid]}
>
{ ({error, isLoading, data}) => {
return children({
error,
isLoading,
subscription: data.length > 0 ? data : null,
})
}}
</FirestoreCollection>
}}
</FirebaseAuth>
)
export default FireflySubscription
我試圖用另一種方法通過它,但“范圍”沒有通過:
getPostSubscriptions = stripePlanId => {
return <FireflySubscription>
// it gets these arguments from FireflySubscription function above
{ ({error, isLoading, subscription}) => {
if (error) {
return <Error error={error} />
}
if (isLoading) {
return <p>loading...</p>
}
if (!subscription) {
return <div>
<p><strong>Subscribe to get paid features</strong></p>
..etc...
</div>
}
..etc...
}}
</FireflySubscription>
}
render() {
return this.getPostSubscriptions(this.props.stripePlanId)
}
}
任何線索都非常感謝! 如果有幫助,我正在改編的原始代碼來自https://github.com/sampl/firefly 。
使用渲染道具
術語“render prop”指的是一種在 React 組件之間共享代碼的技術,使用值為 function 的 prop。
帶有 render prop 的組件需要一個 function ,它返回一個 React 元素並調用它,而不是實現自己的渲染邏輯。
ParentPost 組件:
const ParentPost = () => {
<Subscription auth={auth} stripeAmount={post.amount} stripePlanId={post.planid}>
{(stripePlanId) => <FireflySubscription stripePlanId={stripePlanId}/>}
</Subscription>
};
訂閱組件:在您的渲染方法中,將stripePlanId
作為道具傳遞給children
class Subscription extends React.Component {
// https://stripe.com/docs/checkout#integration-custom
componentDidMount() {
this.stripeCheckout = window.StripeCheckout.configure({
// ...etc...
email: this.props.auth.email
});
}
newSubscription = () => {
var stripePlanId = this.props.stripePlanId;
this.stripeCheckout.open({
amount: this.props.stripeAmount, // in cents
description: this.props.stripePlanId,
token: function(token) {
createSubscription(token, stripePlanId);
}
});
};
render() {
<div>
...
{this.props.children(this.props.stripePlanId)}
...
</div>
}
}
FireflySubscription 組件:在這里,像這樣從父級接收stripePlanId
:。
const FireflySubscription = ({children, stripePlanId}) => (
<FirebaseAuth>
{({isLoading, error, auth}) => {
if (error || isLoading || !auth) {
//it pushes these arguments to the parent function
return children({
error,
isLoading,
subscription: null,
})
}
//const stripePlanId = stripePlanIdFromParent; // dont need this as we are destructuring from props
// when working this should return the subscription for only this planId
if (stripePlanId) {
...
通過您引用的存儲庫,您似乎正在從 Subscription 組件中呈現FireflySubscription
,例如
class Subscription extends React.Component {
// other code here
render() {
return (
<FireflySubscription>
{ ({error, isLoading, subscription}) => {
/*Some components here*/
}}
</FireflySubscription>
)
}
}
考慮到上述情況,最簡單的解決方案是將stripePlanId
作為道具傳遞給FireflySubscription
組件,並在組件內與子組件一起接收它
現在stripePlanId
是在Subscription
組件中計算出來的,它可以很容易地直接從父級傳遞給FireflySubscription
的子級,而不必擔心它會通過 FireflySubscription 路由
所以解決方案看起來像
class Subscription extends React.Component {
// other code here
render() {
return (
<FireflySubscription stripePlanId={this.props.stripePlanId}>
{ ({error, isLoading, subscription}) => {
// stripePlanId can be passed on to any children here using this.props.stripePlanId directly
/*Some components here*/
}}
</FireflySubscription>
)
}
}
現在在 FireflySubscription 中,您將使用它作為
const FireflySubscription = ({children, stripePlanId}) => (
<FirebaseAuth>
{ ({isLoading, error, auth}) => {
if (error || isLoading || !auth) {
//it pushes these arguments to the parent function
return children({
error,
isLoading,
subscription: null,
})
}
if (stripePlanId) {
return <FirestoreCollection
path="subscriptions"
filter={[['createdBy', '==', auth.uid], ['stripePlanId','==', stripePlanId]]}
>
{ ({error, isLoading, data}) => {
return children({
error,
isLoading,
subscription: data.length > 0 ? data : null,
})
}}
</FirestoreCollection>
}
return <FirestoreCollection
path="subscriptions"
filter={['createdBy', '==', auth.uid]}
>
{ ({error, isLoading, data}) => {
return children({
error,
isLoading,
subscription: data.length > 0 ? data : null,
})
}}
</FirestoreCollection>
}}
</FirebaseAuth>
)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.