Denver Dang
Denver Dang

Reputation: 2615

Send click event and state from child to parent

I have a parent component that looks something like this:

import { useState } from "react"
import MyAppChild from "./components/my_app_child";
import "./my_app_parent.scss"

const MyAppParent = (props) => {

    function POST(path, data) {
        return fetch(`http://localhost:5000${path}`,
            {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify(data)
            }
        )
    }

    const [day, setDay] = useState('14');
    const [hour, setHour] = useState('19');
    const [data, setData] = useState([])

    const onChangeDay = e => {
        setDay(e.target.value)
    }
    
    const onClick = e => {
        e.preventDefault();
        POST('/api', { day: day, hour: hour}).then(
            async (response) => {
                const json = await response.json()
                setData(json.returnData)
            }
        )
    }

    return (
        <>
            <div className="content-wrapper">
                    <div className="date">
                        <div>
                            <label>Day</label>
                            <input value={day} onChange={onChangeDay} />
                        </div>
                    </div>
                    <button type="button" onClick={onClick}>
                       Get data
                    </button>
                    
                    
                    <div className="my-app-child-wrapper">
                        <MyAppChild
                            day={day}
                            hour={hour}
                            data={data}
                        />
                    </div>
                    
                </div>
                
            </div>
        </>
    )

}

export default MyAppParent;

Basically the parent has one input field (day). I can fill it out with a number, click the Get data button, and the API will return some data (returnData) I can then feed to my child component, along with the other values, which then outputs something.

My child component looks something like this:

import { useState } from "react"
import "./my_app_child.scss"

const MyAppChild = (props) => {

    const [hour, setHour] = useState('')

    return (
        <>
            <div className="wrapper">
                {props.data.map((value, i) =>
                    <div key={i} onClick={() => {setHour(i)}}>{value}</div>
                )}
            </div>
        </>
    )

}

export default MyAppChild;

So the idea here is that the divs that are created from the mapping are clickable. When they are clicked I would like to send the new state of hour back to the parent, so that the parent hour state is also changed and then run the const onClick again to fetch some new data with the new changed state.

But I am not sure how to send the new hour state back to the parent and then initiate the API call again.

Upvotes: 0

Views: 370

Answers (1)

Dave
Dave

Reputation: 7717

The short answer is to pass hour and setHour to your child as props (not just hour), and remove the useState() in the child element. Then your onClick will call the parent's function and, update the value causing a re-render, and the child's presentation will be updated.

You have some typo's and other issues in the code snippets above.

Upvotes: 1

Related Questions