Skip to content
Advertisement

How to pass a state to a Parent component if I have a button triggering the state in the 2nd Child in React

Hi there,

The issue that I faced recently is the next:

I have a parent component MainPage, that has child components ModalJoin (is not shown by default) and ExploreProjects in it. This ExploreProjects component has its own child component ProjectCard which has a button that is supposed to change a state so ModalJoin is shown. Does anyone have a solution of how do I bind all these, so when the button is clicked ->useState changes to true and ModalJoin pops up? Been trying to link them properly the whole day but still didn’t find a solution. Would appreciate any help!

Have the following files:

Main page

import React, {useState} from 'react'



import ExploreProjects from './ExploreProjects'
import ModalJoin from './ModalJoin'

export default function MainPage() {
    const [isOpened, setIsOpened] = useState(false)





    return (
        <div>
            
            <div className='app'>
                <div className="app__body">
                    
                    <ExploreProjects/>
                </div>
                
            </div>

            <ModalJoin openModal={isOpened} onClose={() => setIsOpened(false)}/>
        </div>
    )
}

ExploreProjects


import React from 'react'
import './ExploreProjects.css'
import ProjectCard from './ProjectCard'

function ExploreProjects() {
    return (
        <div className='explore__projects'>

            <div className="filters__section">
                <div className='filter__item'>
                    <h3>Location</h3>
                    <img src="/images/chevronDown.svg" alt=""/>
                </div>
                <div className='filter__item'>
                    <h3>Industry</h3>
                    <img src="/images/chevronDown.svg" alt=""/>
                </div>
                <div className='filter__item'>
                    <h3>Company</h3>
                    <img src="/images/chevronDown.svg" alt=""/>
                </div>
                <div className='filter__item'>
                    <h3>Complexity</h3>
                    <img src="/images/chevronDown.svg" alt=""/>
                </div>
                <div className='filter__item'>
                    <h3>Duration</h3>
                    <img src="/images/chevronDown.svg" alt=""/>
                </div>

            </div>
            <div className="projects__section">
            <ProjectCard />
            <ProjectCard />
            <ProjectCard />
            <ProjectCard />
            <ProjectCard />
            <ProjectCard />
            </div>


        </div>
    )
}

export default ExploreProjects


ProjectCard

import React, {useState} from 'react'
import './ProjectCard.scss'

export default function ProjectCard({ src, logo, headline, companyName,
    complexity, description, projectType, tag }) {
const [setIsOpened] = useState(false)

    return (
        <div className='project__card'>
            <div className="project__card__header">
                <img src="/images/rehauIcon.png" alt="" className='company__logo' />

                <h3>Logistics Project</h3>
                <div className="project__card__company">
                    <img src="/images/buildingIcon.svg" alt="" />
                    <p>Rehau</p>
                    <p>/</p>
                    
                    <img src="/images/locationIcon.svg" alt="" />
                    <p>Berlin</p>

                    
                </div>

                <div className="project__card__complexity">
                    <div className="basic__complexity"></div>
                        <p>Basic</p>
                </div>


            </div>

            <div className="project__card__body">
                <div>
                    <h3>Task:</h3>
                    

                </div>


                <span>Text

                    <button>More</button>
                </span>
            </div>
            <div className="project__card__bottom">
                <div className="project__card__time">
                    <p>15m ago</p>
                </div>
                <div className="project__card__recruitment">
                    <p>Job opportunity</p>
                </div>
                <div className="project__card__teams">
                    <p>1/2 teams joined</p>
                </div>
                <div className="project__card__tag">
                    <p>#supplychain</p>
                </div>



            </div>
            <div className="project__card__right">

                <img src="images/imgHero.png" alt="" className='project__video__info' />
                <div onClick={ () => this.setIsOpened(true)} className="join__project__button">
                    <p>Join</p>
                </div>

            </div>

        </div>
    )
}

ModalJoin

import React from 'react'


export default function ModalJoin({openModal, onClose}) {
    if (!openModal) return null
    return (
        <div>
            <button onClick={onClose}>Close</button>
            HEEEYYYYYY
        </div>
    )
}

Advertisement

Answer

I commented:

You’ll need to pass a callback prop down <ExploreProjects onOpenModalJoin={callback} />, and then pass the same callback down from ExploreProjects down to ProjectCard. Then in project card on the button click, you would call that callback.

This is a more full explanation:

export default function MainPage() {
    const [isOpened, setIsOpened] = useState(false);
    const callback = () => setIsOpened(true);
    ...
    <ExploreProjects onOpenModalJoin={callback} />
function ExploreProjects(props) {
    ...
    <ProjectCard onOpenModalJoin={props.onOpenModalJoin} />
    ...

And then inside ProjectCard, you would have

   onClick={props.onOpenModalJoin}
User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement