删除 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();