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.tsx
.Add the
ProjectFormProps
interface, with anonCancel
event handler that takes no parameters and returnsvoid
.Update the
cancel
button and add aclick
event to invoke the function passed into theonCancel
prop
.src\projects\ProjectForm.tsx
import React from 'react';
+ interface ProjectFormProps {
+ onCancel: () => void;
+ }
- function ProjectForm() {
+ function ProjectForm({ onCancel }: ProjectFormProps) {
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>
);
}
export default ProjectForm;
In a parent component, implement a function and pass it as a prop to a child component
In
src\projects\ProjectList.tsx
add acancelEditing
event handler toProjectList
that sets the state of the component so thateditingProject
is an empty object{}
. See the details in the next step.Wire up the onCancel event of the
<ProjectForm />
component rendered in theProjectList
to thecancelEditing
event handler.src\projects\ProjectList.tsx
...
function ProjectList({ projects }: ProjectListProps) {
const [projectBeingEdited, setProjectBeingEdited] = useState({});
const handleEdit = (project: 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.