简体   繁体   English

如何使用 {children} 将 React Component 道具传递给子 function?

[英]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.

相关问题 将本机传递函数作为prop反映到子组件 - React Native pass function to child component as prop React:将组件作为道具传递而不使用 this.props.children - React: Pass component as prop without using this.props.children 将 Children 道具传递给 React Memo 组件 - Pass Children prop to React Memo component 与Typescript反应:无法将函数prop传递给子组件 - React with Typescript:Unable to pass function prop to child component 使用 React Hooks,当我将 prop 从父组件传递给子组件时,子组件中的 prop 未定义 - Using React Hooks, when I pass down a prop from parent to a child component, the prop in the child component is undefined 如果 Prop 被称为子组件,如何将数据传递给组件 - React JS - How to pass data to component if it's Prop is mentioned as child - React JS 如何在反应导航 v5 中将导航道具传递给子组件 - How to pass navigation prop to child component in react navigation v5 我如何在React中使用children道具删除组件 - How can I remove a component using the children prop in React React 组件中的 children 属性 - children prop in React component 如何将 function 作为道具传递给子组件并在 Vue 中从那里调用它? - How to pass function as a prop to child component and call it from there in Vue?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM