Reputation: 331
I want to delete a post by click on delete button and then go to home page (with redux in functional component) but when I click on the button it doesn't delete the post and just return to home page and show all posts.
this is my post.js
component:(where I want to delete a post by click)
import React from "react";
import { useParams,useNavigate } from "react-router-dom";
import { useSelector, useDispatch } from 'react-redux';
const Post = () => {
const { id } = useParams();
const navigate = useNavigate();
const dispatch = useDispatch();
const post = useSelector(state =>
state.posts.find(post => post.id === id)
);
const handleDelete=(id)=>{
dispatch({type:'DELETE_POST',id:id});
console.log(id)
navigate('/');
}
return post ? (
<div className="post">
<h4 className="center">{post.title}</h4>
<p className="center">{post.body}</p>
<div className="center">
<button className="btn grey" onClick={handleDelete}>Delete Post</button>
</div>
</div>
) : (<div className="center">
"Loading post ..."
</div>
);
};
export default Post;
and this is my reducer:
const initState = {
posts: [
{
id: "1",
title: "Squirtle Laid an Egg",
body: "Lorem ipsum, dolor sit amet consectetur adipisicing elit. Consequatur voluptate laborum perferendis, enim repellendus ipsam sunt autem at odit dolorum, voluptatum suscipit iste harum cum magni itaque animi laudantium fugiat",
},
{
id: "2",
title: "Charmander Laid an Egg",
body: "Lorem ipsum, dolor sit amet consectetur adipisicing elit. Consequatur voluptate laborum perferendis, enim repellendus ipsam sunt autem at odit dolorum, voluptatum suscipit iste harum cum magni itaque animi laudantium fugiat",
},
{
id: "3",
title: "a Helix Fossil was Found",
body: "Lorem ipsum, dolor sit amet consectetur adipisicing elit. Consequatur voluptate laborum perferendis, enim repellendus ipsam sunt autem at odit dolorum, voluptatum suscipit iste harum cum magni itaque animi laudantium fugiat",
},
],
};
const rootReducer = (state = initState, action) => {
if (action.type === "DELETE_POST") {
let newPosts = state.posts.filter((post) => {
return action.id !== post.id;
});
return {
...state,
posts: newPosts,
};
}
return state;
};
export default rootReducer;
thank you for your help.
Upvotes: 1
Views: 1747
Reputation: 884
I think the problem is same variable name in handleDelete function. Change code like this. Variable scope is polluted by event parameter "id".
const handleDelete = (event) => {
console.log(id)
dispatch({type: 'DELETE_POST', id: id});
navigate('/');
}
And here is my full code.
import {Route, Routes, useNavigate, useParams} from "react-router-dom";
import React, {Fragment} from "react";
import {useDispatch, useSelector} from 'react-redux';
function App() {
return (
<Routes>
<Route path="/" element={<Main/>}/>
<Route path="/post/:id" element={<Post/>}/>
</Routes>
);
}
const Main = () => {
const navigate = useNavigate();
const posts = useSelector(state => state.posts);
return (
<div>
<div>Main</div>
{posts.map(post =>
<Fragment key={post.id}>
<h4 className="center">{post.title}</h4>
<p className="center">{post.body}</p>
</Fragment>)
}
<button onClick={() => navigate('/post/1')}>click me</button>
</div>
);
}
const Post = () => {
const {id} = useParams();
const navigate = useNavigate();
const dispatch = useDispatch();
const post = useSelector(state => {
console.log(state)
return state.posts.find(post => post.id === id)
}
);
const handleDelete = (event) => {
console.log(id)
dispatch({type: 'DELETE_POST', id: id});
navigate('/');
}
return post ? (
<div className="post">
<h4 className="center">{post.title}</h4>
<p className="center">{post.body}</p>
<div className="center">
<button className="btn grey" onClick={handleDelete}>Delete Post</button>
</div>
</div>
) : (<div className="center">
"Loading post ..."
</div>
);
};
export default App;
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import {BrowserRouter} from "react-router-dom";
import {Provider} from "react-redux";
import {createStore} from "redux";
const initState = {
posts: [
{
id: "1",
title: "Squirtle Laid an Egg",
body: "Lorem ipsum, dolor sit amet consectetur adipisicing elit. Consequatur voluptate laborum perferendis, enim repellendus ipsam sunt autem at odit dolorum, voluptatum suscipit iste harum cum magni itaque animi laudantium fugiat",
},
{
id: "2",
title: "Charmander Laid an Egg",
body: "Lorem ipsum, dolor sit amet consectetur adipisicing elit. Consequatur voluptate laborum perferendis, enim repellendus ipsam sunt autem at odit dolorum, voluptatum suscipit iste harum cum magni itaque animi laudantium fugiat",
},
{
id: "3",
title: "a Helix Fossil was Found",
body: "Lorem ipsum, dolor sit amet consectetur adipisicing elit. Consequatur voluptate laborum perferendis, enim repellendus ipsam sunt autem at odit dolorum, voluptatum suscipit iste harum cum magni itaque animi laudantium fugiat",
},
],
};
const rootReducer = (state = initState, action) => {
if (action.type === "DELETE_POST") {
let newPosts = state.posts.filter((post) => {
return action.id !== post.id;
});
return {
...state,
posts: newPosts,
};
}
return state;
};
const store = createStore(rootReducer)
ReactDOM.render(
<React.StrictMode>
<Provider store={store}>
<BrowserRouter>
<App/>
</BrowserRouter>
</Provider>
</React.StrictMode>,
document.getElementById('root')
)
;
reportWebVitals();
Upvotes: 1
Reputation: 203587
The handleDelete
handler is expecting a post id
to be passed to it.
const handleDelete = (id) => {
dispatch({ type: 'DELETE_POST', id: id });
console.log(id)
navigate('/');
}
But you appear to be passing the button's onClick
event object instead.
<button
className="btn grey"
onClick={handleDelete} // <-- onClick event is passed to callback
>
Delete Post
</button>
Use an anonymous callback function to pass the post.id
to the handler.
<button
className="btn grey"
onClick={() => handleDelete(post.id)}
>
Delete Post
</button>
Or convert handleDelete
to a curried function to close over the post id
in callback scope and return an onClick
handler function.
const handleDelete = (id) => () => {
dispatch({ type: 'DELETE_POST', id });
console.log(id)
navigate('/');
}
...
<button
className="btn grey"
onClick={handleDelete(post.id)}
>
Delete Post
</button>
Upvotes: 1