如何在ReactJS中将值从子组件传递给父组件

问题描述

我具有以下功能组件:

CHILD:

import React from 'react'

import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'

const ProductsQtde = props => {

    let [productQtde,setProductQtde] = React.useState(1)

    const changeQtde = arg => {
        if (arg === "increase") {
            setProductQtde(productQtde + 1)
        } else if (arg === 'decrease') {
            productQtde > 1 ? setProductQtde(productQtde - 1) : setProductQtde(1)
        }
    }


    return (
        <div className="product-qtde d-flex justify-content-around align-items-center border">
            <p style={{margin: '0'}}>{productQtde}</p>
            <div className="product-qtde-arrows d-flex flex-column justify-content-between">
                <FontAwesomeIcon onClick={() => changeQtde('increase')} icon="chevron-up" size="xs"/>
                <FontAwesomeIcon onClick={() => changeQtde('decrease')} icon="chevron-down" size="xs"/>
            </div>
        </div>
    )
}

export default ProductsQtde

PARENT:

import React from 'react'

import ProductQtde from '../../Shared/UI/ProductsQtde/ProductsQtde'


    const Cart = props => {
    
        return (
            <div>
                <ProductQtde />
            </div>
        )
    }
    
    export default Cart

这是结果:

enter image description here

可以看出,它是一种输入数字,因此它的作用是增加和减少所需数量数量

但是,由于它是一个共享的组件,并且我想使其不仅是UI组件而能够工作,所以我在组件本身中将其值设置为状态productQtde,这样我就不会无需在我正在使用的changeQtde的每个父组件中创建函数ProductsQtde

重点是,我想继续在子组件中更改此值,在父组件中接收它并在其中使用它。我知道我可以在父组件中设置一个函数一个状态,然后将其作为道具发送给子组件,但是正如我所说,我希望将该功能保留在子组件中。

有可能这样做吗?

我找到了一些回答类似问题的帖子和教程,但是都没有给我我需要的具体答案。

解决方法

我一直在挖掘,然后在这篇文章的帮助下,我可以实现自己的目标:https://dev.to/pnkfluffy/passing-data-from-child-to-parent-with-react-hooks-1ji3

解决方案非常简单,位于回调函数上。

我正在做的是将一个函数作为道具传递给子组件,而这又是调用此函数并将更新后的值作为参数发送给父组件。 Cart组件接收该值作为参数,并使用它来更新自己的状态。

CHILD:

import React from 'react'

import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'

const ProductsQtde = props => {

    let [productQtde,setProductQtde] = React.useState(1)

    const changeQtde = arg => {
        if (arg === "increase") {
            setProductQtde(productQtde + 1)
            props.changeQtdeCallBack(productQtde + 1) // => Callback function
        } else if (arg === 'decrease') {
            productQtde > 1 ? setProductQtde(productQtde - 1) : setProductQtde(1)
            props.changeQtdeCallBack(productQtde - 1) // => Callback function
        }
    }


    return (
        <div className="product-qtde d-flex justify-content-around align-items-center border">
            <p style={{margin: '0'}}>{productQtde}</p>
            <div className="product-qtde-arrows d-flex flex-column justify-content-between" >
                <FontAwesomeIcon onClick={() => changeQtde('increase')} icon="chevron-up" size="xs"/>
                <FontAwesomeIcon onClick={() => changeQtde('decrease')} icon="chevron-down" size="xs"/>
            </div>
        </div>
    )
}

export default ProductsQtde

PARENT:

    import React from 'react'
    
    import ProductQtde from '../../Shared/UI/ProductsQtde/ProductsQtde'
    
    
    const Cart = props => {
    
        const [qtde,setQtde] = React.useState(1)
        
        
        return (
            <div>
                <ProductQtde 
                   {/* // => function being sent as props */}
                   changeQtdeCallBack={qtde => setQtde(qtde)} 
                />
            </div>
        )
    }
    
    export default Cart