Как передавать значения из дочернего компонента в родительский в ReactJS

#javascript #reactjs #components

#javascript #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
  

Это результат:

введите описание изображения здесь

Как можно видеть, это своего рода входное число, поэтому его функция заключается в увеличении и уменьшении количества всего, что необходимо.

Однако, поскольку это общий компонент, и я хотел бы сделать его функциональным, а не просто компонентом пользовательского интерфейса, я устанавливаю его значения в самом компоненте с состоянием productQtde , так что мне не нужно создавать функцию changeQtde в каждом родительском компоненте, который я использую ProductsQtde .

Дело в том, что я хочу продолжать изменять это значение в дочернем компоненте, получать его в родительском и использовать его там. Я знаю, что мог бы установить функцию и состояние в родительском компоненте и отправить его дочернему в качестве реквизита, но, как я уже сказал, я бы хотел сохранить функциональность внутри дочернего компонента.

Возможно ли это сделать?

Я нашел несколько сообщений и руководств, отвечающих на похожие вопросы, но ни один из них не дал мне конкретного ответа, который мне нужен.

Комментарии:

1. Неважно, что вы хотите, если вы хотите, чтобы ваше значение находилось за пределами вашего дочернего компонента (то есть в родительском)…. вам нужно создать связь между дочерним компонентом и родительским. Это может сделать простой prop.

2. Это антишаблон. Не могли бы вы уточнить, пожалуйста? Как вы хотите получить доступ к этому значению из родительского компонента? Не прерывайте однонаправленный поток (сверху вниз)

3. @Quentin Grisel Существует взаимосвязь, я это понимаю. Но как бы я передал реквизит от дочернего компонента к родительскому?

4. @Dupocas Я это понимаю. How do you want to access this value from the parent component? , это именно то, о чем я спрашиваю, способ сделать это.

5. I know I could set a function and a state in the parent component and send it to the child as props Ты буквально сказал, что знаешь, как это сделать, чувак. Ваш prop — это просто установщик useState .

Ответ №1:

Я продолжал копать, затем с некоторой помощью этой статьи я смог достичь своей цели: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