DEV Community

marthaeochoa
marthaeochoa

Posted on

React information flow.

So we know to pass information from a parent down to a child we use props. Well, as it turns out, to do the opposite: it is NOT that simple.

So how can we send information from a child component to its parent component? You would only need to pass information from a child to a parent component when something happening in the child component directly affects the parent. Take a delete button for example. A delete button that removes something from the application.

The way we would handle this is by creating a callback function in the parent component and passing it down to the child as a prop.
In my application, I needed to make a delete button functional, but the delete button lives in a nested child component.

So I have app

function app () {
 const [projects, setProjects] = useState([]);
return (
<ProjectList projects={projects} />
)
}
Enter fullscreen mode Exit fullscreen mode

And ProjectList which returns all the projects I want to display in my application (with props passed down by app).

function ProjectList ({ projects}) {

    return projects.map(project => {
        return (
        <ProjectItem 
        key={project.id} 
        project={project} 
        />
     )
    })
};

return (
          <section>
            <table>
            <tr>
                    <td><h3>Title</h3></td>
                    <td><h3>Description</h3></td>
             </tr>
             {renderProjects(projects)}
            </table>
        </section>
)
}
Enter fullscreen mode Exit fullscreen mode

I created a table to better fit my layout, but as you can see, I created a seperate component to take care of each individual Project in my list of projects. That component looks like this:

function ProjectItem({ project }) {

    const { id, title, description } = project 

    return(
       <tr>
        <td>{title}</td>
        <td>{description}</td>
        <td className="delete-button">
            <button className="delete-button"> x </button>
        </td>
        </tr>
    )
}
Enter fullscreen mode Exit fullscreen mode

So in order to make my delete button functional, I need to get the click to reach all the way to the app component since Projects state lives in app. The app component displays ProjectList and ProjectList needs ProjectListItem in order to display each project. So let's create the call back function.

function app () {
const [projects, setProjects] = useState([]);

  function onProjectDelete (projectId) {
    setProjects(projects => projects.filter(Project => Project.id !== projectId))
};

return (
<ProjectList projects={projects} onProjectDelete={onProjectDelete} />
)
}
Enter fullscreen mode Exit fullscreen mode

Then accept it in our ProjectList component and pass it down to our ProjectItem component.

function ProjectList ({ projects, onProjectDelete }) {

    return projects.map(project => {
        return (
        <ProjectItem 
        key={project.id} 
        project={project} 
        onProjectDelete={onProjectDelete}
        />
     )
    })
};
.......
Enter fullscreen mode Exit fullscreen mode

Now we accept it in our ProjectItem component. We now must create a function that will take in onProjectDelete and be handled by the onClick event.

function ProjectItem({ project, onProjectDelete }) {

    const { id, title, description } = project 

    function handleDelete () {
        onProjectDelete(id);
    }

    return(
       <tr>
        <td>{title}</td>
        <td>{description}</td>
        <td className="delete-button">
            <button className="delete-button" onClick={handleDelete}> x </button>
        </td>
        </tr>
    )
}
Enter fullscreen mode Exit fullscreen mode

And there we have sucessfully created a way to connect the information happening in ProjectItem all the way back up to state in the App component.

Top comments (0)