I have a spring boot api with crud functionalities, on my react frontend I have this, which is a dashboard component and inside i am rendering a list of ProjectItem components and passing them to the dashboard component as props.
When I delete a project I'd like it to immediately remove the project from the component without having to refresh for it to happen. Since I am passing the props down to my Dashboard component I am a bit confused on how to achieve this.
ProjectItem.js
- BackendService is a service class with axios calls for the crud operations
import React, { useEffect, useState } from 'react'
import BackendService from '../services/BackendService';
import { Link } from 'react-router-dom';
import { useParams } from 'react-router';
const ProjectItem = ({projectName, projectIdentifier, description}) => {
const onDeleteClick = (id) => {
if (window.confirm("Are you sure you want to delete this project?")) {
BackendService.deleteProject(id)
.then()
.catch((err) => {
console.log(err.response);
});
alert("Project with ID " id " was deleted successfully");
}
};
return (
<div className="container">
<div className="card card-body bg-light mb-3">
<div className="row">
<div className="col-2">
<span className="mx-auto">{projectIdentifier}</span>
</div>
<div className="col-lg-6 col-md-4 col-8">
<h3>{projectName}</h3>
<p>{description}</p>
</div>
<div className="col-md-4 d-none d-lg-block">
<ul className="list-group">
<Link to="">
<li className="list-group-item update">
<i className="fa fa-edit pr-1"> Update Project Info</i>
</li>
</Link>
<button
className="list-group-item delete"
onClick={() => onDeleteClick(projectIdentifier)}
>
<i className="fa fa-minus-circle pr-1"> Delete Project</i>
</button>
</ul>
</div>
</div>
</div>
</div>
);
};
export default ProjectItem;
Dashboard.js
- Where the ProjectItem components are rendered
import React, { useEffect, useState } from 'react'
import { Link } from 'react-router-dom'
import BackendService from '../services/BackendService'
import AppNavbar from './AppNavbar'
import ProjectItem from './ProjectItem'
const Dashboard = () => {
const [project, setProject] = useState({
projectName: "",
projectIdentifier: "",
description: "",
});
useEffect(() => {
BackendService.getProjects().then((res) => {
setProject(res.data);
});
}, []);
return (
<div className="projects">
<AppNavbar />
<div className="container">
<div className="row">
<div className="col-md-12">
<h1 className="display-4 text-center">Projects</h1>
<Link to="/addProject">
<button className="btn btn-warning">Create Project</button>
</Link>
{project &&
Object.values(project).map((prj) => {
return (
<div>
<ProjectItem key={prj.id}
projectName={prj.projectName}
projectIdentifier={prj.projectIdentifier}
description={prj.description}
/>
</div>
);
})}
<hr />
</div>
</div>
</div>
</div>
);
};
export default Dashboard
CodePudding user response:
If you want to remove item without refresh the page then you have to call setProject
and set it to new project list after BackendService.deleteProject
request done in onDeleteClick
.
https://reactjs.org/docs/state-and-lifecycle.html
CodePudding user response:
You are deleting your project item in your backend but React
doesn't know as you are doing. Try this :
import React, { useEffect, useState } from 'react'
import { Link } from 'react-router-dom'
import BackendService from '../services/BackendService'
import AppNavbar from './AppNavbar'
import ProjectItem from './ProjectItem'
const Dashboard = () => {
const [project, setProject] = useState(null);
const onDeleteClick = (id) => {
if (window.confirm("Are you sure you want to delete this project?")) {
BackendService.deleteProject(id)
.then(()=>{
// here you delete the project and update your state
// I don't know if you are receiving many project in your fetch, if not do :
setProject(null);
// If it is you do something like this :
// setProject(project.filter(pr => pr.id !== id))
})
.catch((err) => {
console.log(err.response);
});
alert("Project with ID " id " was deleted successfully");
}
};
useEffect(() => {
BackendService.getProjects().then((res) => {
setProject(res.data);
});
}, []);
return (
<div className="projects">
<AppNavbar />
<div className="container">
<div className="row">
<div className="col-md-12">
<h1 className="display-4 text-center">Projects</h1>
<Link to="/addProject">
<button className="btn btn-warning">Create Project</button>
</Link>
{project &&
Object.values(project).map((prj) => {
return (
<div>
<ProjectItem key={prj.id}
projectName={prj.projectName}
projectIdentifier={prj.projectIdentifier}
description={prj.description}
onDeleteClick={onDeleteClick}
/>
</div>
);
})}
<hr />
</div>
</div>
</div>
</div>
);
};
export default Dashboard
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
import React, { useEffect, useState } from 'react'
import BackendService from '../services/BackendService';
import { Link } from 'react-router-dom';
import { useParams } from 'react-router';
const ProjectItem = ({projectName, projectIdentifier, description, onDeleteClick}) => {
return (
<div className="container">
<div className="card card-body bg-light mb-3">
<div className="row">
<div className="col-2">
<span className="mx-auto">{projectIdentifier}</span>
</div>
<div className="col-lg-6 col-md-4 col-8">
<h3>{projectName}</h3>
<p>{description}</p>
</div>
<div className="col-md-4 d-none d-lg-block">
<ul className="list-group">
<Link to="">
<li className="list-group-item update">
<i className="fa fa-edit pr-1"> Update Project Info</i>
</li>
</Link>
<button
className="list-group-item delete"
onClick={() => onDeleteClick(projectIdentifier)}
>
<i className="fa fa-minus-circle pr-1"> Delete Project</i>
</button>
</ul>
</div>
</div>
</div>
</div>
);
};
export default ProjectItem;
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>