Lab 13: More Component Communication
Objectives
- In a child component, accept a function as a prop and invoke it
- In a parent component, implement a function and pass it as a prop to a child component
Steps
In a child component, accept a function as a prop and invoke it
- Open the file - src\projects\ProjectForm.js.
- In the - ProjectFormPropsinterface, add an- onCancelevent handler that takes no parameters and returns- void.
- Update the - cancelbutton and add a- clickevent to invoke the function passed into the- onCancel- prop.- src\projects\ProjectForm.jsimport React from 'react';+ import PropTypes from 'prop-types';- function ProjectForm() {+ function ProjectForm({ onCancel }) {return (<form className="input-group vertical"><label htmlFor="name">Project Name</label><input type="text" name="name" placeholder="enter name" /><label htmlFor="description">Project Description</label><textarea name="description" placeholder="enter description" /><label htmlFor="budget">Project Budget</label><input type="number" name="budget" placeholder="enter budget" /><label htmlFor="isActive">Active?</label><input type="checkbox" name="isActive" /><div className="input-group"><button className="primary bordered medium">Save</button><span /><button type="button" className="bordered medium"+ onClick={onCancel}>cancel</button></div></form>);}+ ProjectForm.propTypes = {+ onCancel: PropTypes.func.isRequired+ };export default ProjectForm;
In a parent component, implement a function and pass it as a prop to a child component
- In - src\projects\ProjectList.jsadd a- cancelEditingevent handler to- ProjectListthat sets the state of the component so that- editingProjectis an empty object- {}.
- Wire up the onCancel event of the - <ProjectForm />component rendered in the- ProjectListto the- cancelEditingevent handler.- src\projects\ProjectList.js
...
function ProjectList({ projects }) {
  const [projectBeingEdited, setProjectBeingEdited] = useState({});
  const handleEdit = (project) => {
    setProjectBeingEdited(project);
  };
+  const cancelEditing = () => {
+    setProjectBeingEdited({});
+  };
  return (
    <div className="row">
      {projects.map((project) => (
        <div key={project.id} className="cols-sm">
          {project === projectBeingEdited ? (
            <ProjectForm
+              onCancel={cancelEditing}
            />
          ) : (
            <ProjectCard project={project} onEdit={handleEdit} />
          )}
        </div>
      ))}
    </div>
  );
}
export default ProjectList;
- Verify the application is working by following these steps:- Open the application in your browser and refresh the page.
- Click the edit button for a project.
- Verify the <ProjectCard />is removed and replaced by the<ProjectForm/>.The <ProjectForm/>will be empty at this point. We will fill in the data in a future lab.
- Click the cancel button on the form.
- Verify the <ProjectForm/>is removed and replaced by the<ProjectCard />.
 
This lab is conceptually very similar to Lab 11 in that we are invoking a function on a parent component in a child component.