[英]How to pass React Component prop to child function using {children}?
I'm new to React so this may be something obvious but I can't pass through a prop to a function that creates Components from its parent.我是 React 的新手,所以这可能很明显,但我不能通过道具传递给从其父级创建组件的 function。
I can pass props to child components, but the same doesn't work for functions.我可以将道具传递给子组件,但同样不适用于函数。
I have <Subscription>
which I can pass through arguments like so, from its parent post
:我有
<Subscription>
我可以通过 arguments 像这样,从它的父post
:
<Subscription auth={auth} stripeAmount={post.amount} stripePlanId={post.planid}/>
This creates a Stripe subscription.这将创建一个 Stripe 订阅。 I want to limit the subscription to subscribe to the
stripePlanId
which I do so via:我想限制订阅以订阅我通过以下方式订阅的
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..
This works great.这很好用。 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 functions it expects to act upon the arguments passed: 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
I have tried to pass it through with another method, but the "scope" does not pass through:我试图用另一种方法通过它,但“范围”没有通过:
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)
}
}
Any clue most appreciated!任何线索都非常感谢! The original code I'm adapting is from https://github.com/sampl/firefly if that helps.
如果有帮助,我正在改编的原始代码来自https://github.com/sampl/firefly 。
Use Render Props使用渲染道具
The term “render prop” refers to a technique for sharing code between React components using a prop whose value is a function.
术语“render prop”指的是一种在 React 组件之间共享代码的技术,使用值为 function 的 prop。
A component with a render prop takes a function that returns a React element and calls it instead of implementing its own render logic.
带有 render prop 的组件需要一个 function ,它返回一个 React 元素并调用它,而不是实现自己的渲染逻辑。
ParentPost Component: ParentPost 组件:
const ParentPost = () => {
<Subscription auth={auth} stripeAmount={post.amount} stripePlanId={post.planid}>
{(stripePlanId) => <FireflySubscription stripePlanId={stripePlanId}/>}
</Subscription>
};
Subscription Component: In your render method, pass stripePlanId
as prop to the children
订阅组件:在您的渲染方法中,将
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 Component: In here, receive the stripePlanId
from the parent like this:. 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) {
...
Going by the repository that you refer, its seems like you are rendering FireflySubscription
from within Subscription component like通过您引用的存储库,您似乎正在从 Subscription 组件中呈现
FireflySubscription
,例如
class Subscription extends React.Component {
// other code here
render() {
return (
<FireflySubscription>
{ ({error, isLoading, subscription}) => {
/*Some components here*/
}}
</FireflySubscription>
)
}
}
Considering the above, the simplest solution for you is to pass on the stripePlanId
as a prop to FireflySubscription
component and receive it inside the component along with children考虑到上述情况,最简单的解决方案是将
stripePlanId
作为道具传递给FireflySubscription
组件,并在组件内与子组件一起接收它
Now that stripePlanId
is calculated inside Subscription
component, it can easily be passed to the children of FireflySubscription
directly from parent without worrying about it being routed through FireflySubscription现在
stripePlanId
是在Subscription
组件中计算出来的,它可以很容易地直接从父级传递给FireflySubscription
的子级,而不必担心它会通过 FireflySubscription 路由
So the solution would look like所以解决方案看起来像
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>
)
}
}
Now in FireflySubscription, you will use it as现在在 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.