如何使用 {children} 将 React Component prop 传递给子函数?
How to pass React Component prop to child function using {children}?
我是 React 的新手,所以这可能是显而易见的事情,但我无法将 prop 传递给从其父级创建组件的函数。
我可以将 props 传递给子组件,但这对函数不起作用。
我有 <Subscription>
,我可以像这样从它的父 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..
效果很好。但是现在要通过 stripePlanId 我无法找到如何传递 stripePlanId
因为它是通过函数呈现的 - 这个 {children}
参数似乎只传递函数,并试图添加参数导致错误,它们不是它期望对传递的参数起作用的函数:
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
我试过用另一种方法通过,但是"scope"没有通过:
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。
The term “render prop” refers to a technique for sharing code between React components using a prop whose value is a function.
A component with a render prop takes a function that returns a React element and calls it instead of implementing its own render logic.
ParentPost 组件:
const ParentPost = () => {
<Subscription auth={auth} stripeAmount={post.amount} stripePlanId={post.planid}>
{(stripePlanId) => <FireflySubscription stripePlanId={stripePlanId}/>}
</Subscription>
};
订阅组件: 在您的渲染方法中,将 stripePlanId
作为 prop 传递给 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) {
...
根据您引用的存储库,您似乎正在从订阅组件中呈现 FireflySubscription
,例如
class Subscription extends React.Component {
// other code here
render() {
return (
<FireflySubscription>
{ ({error, isLoading, subscription}) => {
/*Some components here*/
}}
</FireflySubscription>
)
}
}
考虑到以上情况,最简单的解决方案是将 stripePlanId
作为 prop 传递给 FireflySubscription
组件,并在组件内部接收它以及子组件
现在 stripePlanId
是在 Subscription
组件内部计算的,它可以很容易地直接从父组件传递给 FireflySubscription
的子组件,而不用担心它会通过 FireflySubscription[=19] 进行路由=]
所以解决方案看起来像
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>
)
我是 React 的新手,所以这可能是显而易见的事情,但我无法将 prop 传递给从其父级创建组件的函数。
我可以将 props 传递给子组件,但这对函数不起作用。
我有 <Subscription>
,我可以像这样从它的父 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..
效果很好。但是现在要通过 stripePlanId 我无法找到如何传递 stripePlanId
因为它是通过函数呈现的 - 这个 {children}
参数似乎只传递函数,并试图添加参数导致错误,它们不是它期望对传递的参数起作用的函数:
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
我试过用另一种方法通过,但是"scope"没有通过:
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。
The term “render prop” refers to a technique for sharing code between React components using a prop whose value is a function.
A component with a render prop takes a function that returns a React element and calls it instead of implementing its own render logic.
ParentPost 组件:
const ParentPost = () => {
<Subscription auth={auth} stripeAmount={post.amount} stripePlanId={post.planid}>
{(stripePlanId) => <FireflySubscription stripePlanId={stripePlanId}/>}
</Subscription>
};
订阅组件: 在您的渲染方法中,将 stripePlanId
作为 prop 传递给 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) {
...
根据您引用的存储库,您似乎正在从订阅组件中呈现 FireflySubscription
,例如
class Subscription extends React.Component {
// other code here
render() {
return (
<FireflySubscription>
{ ({error, isLoading, subscription}) => {
/*Some components here*/
}}
</FireflySubscription>
)
}
}
考虑到以上情况,最简单的解决方案是将 stripePlanId
作为 prop 传递给 FireflySubscription
组件,并在组件内部接收它以及子组件
现在 stripePlanId
是在 Subscription
组件内部计算的,它可以很容易地直接从父组件传递给 FireflySubscription
的子组件,而不用担心它会通过 FireflySubscription[=19] 进行路由=]
所以解决方案看起来像
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>
)