为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

冉冉说 2022-06-16 15:14:39
我是 React 的新手,所以这可能很明显,但我不能通过 prop 传递给从其父级创建组件的函数。我可以将道具传递给子组件,但同样不适用于函数。我有<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]}      >任何线索都非常感谢!如果有帮助,我正在改编的原始代码来自https://github.com/sampl/firefly 。
查看完整描述

2 回答

?
蝴蝶不菲

TA贡献1810条经验 获得超4个赞

通过您引用的存储库,您似乎正在FireflySubscription从 Subscription 组件中进行渲染,例如


class Subscription extends React.Component {

    // other code here


    render() {

       return (

           <FireflySubscription>

               { ({error, isLoading, subscription}) => {

                   /*Some components here*/

               }}

           </FireflySubscription>

       )

    }

}

考虑到上述情况,最简单的解决方案是将stripePlanIdas 作为 prop 传递给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>

)


查看完整回答
反对 回复 2022-06-16
?
慕虎7371278

TA贡献1802条经验 获得超4个赞

使用渲染道具


术语“render prop”指的是一种在 React 组件之间共享代码的技术,使用值为函数的 prop。


带有 render prop 的组件接受一个函数,该函数返回一个 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) {

            ...


查看完整回答
反对 回复 2022-06-16
  • 2 回答
  • 0 关注
  • 221 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号