删除 redux 中的项目(功能组件)
delete item in redux (functional component)
我想通过单击删除按钮删除 post 然后转到主页(功能组件中有 redux)但是当我单击按钮时它不会删除 post 并 return 到主页并显示所有 post。
这是我的 post.js
组件:(我想通过单击删除 post)
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;
这是我的减速器:
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;
感谢您的帮助。
问题
handleDelete
处理程序期望将 post id
传递给它。
const handleDelete = (id) => {
dispatch({ type: 'DELETE_POST', id: id });
console.log(id)
navigate('/');
}
但您似乎正在传递按钮的 onClick
事件对象。
<button
className="btn grey"
onClick={handleDelete} // <-- onClick event is passed to callback
>
Delete Post
</button>
解决方案
使用匿名回调函数将 post.id
传递给处理程序。
<button
className="btn grey"
onClick={() => handleDelete(post.id)}
>
Delete Post
</button>
或将 handleDelete
转换为柯里化函数以关闭回调范围内的 post id
和 return 一个 onClick
处理函数。
const handleDelete = (id) => () => {
dispatch({ type: 'DELETE_POST', id });
console.log(id)
navigate('/');
}
...
<button
className="btn grey"
onClick={handleDelete(post.id)}
>
Delete Post
</button>
我认为问题出在 handleDelete 函数中的变量名相同。
像这样更改代码。
变量范围被事件参数“id”污染。
const handleDelete = (event) => {
console.log(id)
dispatch({type: 'DELETE_POST', id: id});
navigate('/');
}
这是我的完整代码。
App.js
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;
index.js
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();
我想通过单击删除按钮删除 post 然后转到主页(功能组件中有 redux)但是当我单击按钮时它不会删除 post 并 return 到主页并显示所有 post。
这是我的 post.js
组件:(我想通过单击删除 post)
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;
这是我的减速器:
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;
感谢您的帮助。
问题
handleDelete
处理程序期望将 post id
传递给它。
const handleDelete = (id) => {
dispatch({ type: 'DELETE_POST', id: id });
console.log(id)
navigate('/');
}
但您似乎正在传递按钮的 onClick
事件对象。
<button
className="btn grey"
onClick={handleDelete} // <-- onClick event is passed to callback
>
Delete Post
</button>
解决方案
使用匿名回调函数将 post.id
传递给处理程序。
<button
className="btn grey"
onClick={() => handleDelete(post.id)}
>
Delete Post
</button>
或将 handleDelete
转换为柯里化函数以关闭回调范围内的 post id
和 return 一个 onClick
处理函数。
const handleDelete = (id) => () => {
dispatch({ type: 'DELETE_POST', id });
console.log(id)
navigate('/');
}
...
<button
className="btn grey"
onClick={handleDelete(post.id)}
>
Delete Post
</button>
我认为问题出在 handleDelete 函数中的变量名相同。 像这样更改代码。 变量范围被事件参数“id”污染。
const handleDelete = (event) => {
console.log(id)
dispatch({type: 'DELETE_POST', id: id});
navigate('/');
}
这是我的完整代码。
App.js
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;
index.js
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();