【问题标题】:React-Redux removing(delete) an item on clickReact-Redux 在点击时删除(删除)一个项目
【发布时间】:2020-06-29 06:55:31
【问题描述】:

我正在学习 react-redux,所以现在我正在尝试创建 react-redux crud 应用程序,这是任何解决方案

这里是回购:repo demo

按钮

<span className="delete_info" onClick={() => deleteComment(comment.id) }>Delete</span>

删除元素的动作创建者

export const removeComment = id =>{
  return{
    type: ActionTypes.DELETE_COMMENTS,
    payload:id
  }
}
// delete comments

export const deleteComment = id =>{
  console.log('ids', id);
  return dispatch =>{
    dispatch(fetchCommentsRequest())
    axios.delete(`/api/v1/todo/${id}`)
    .then(response =>{
      console.log('yeees mom', response.data)
      dispatch(removeComment(id))
    })
    .catch(error =>{
      const erroMsg =error.message;
      console.log('eeeror', erroMsg)
      dispatch(fetchCommentsFailure(erroMsg))
    })
  }
}

这是我的减速器

import * as ActionTypes from '../action-types'

const initialState ={
    data:[],
    error:'',
    comments:[],
    loading:false,
    editing:false
}

const reducer = (state= initialState, action) => {
    switch (action.type) {
        case ActionTypes.FETCH_COMMENTS_REQUEST:
            return{
                ...state,
                loading: true,
            }
        case ActionTypes.FETCH_COMMENTS_SUCCESS:
            return{
                ...state,
                loading:false,
                comments:action.payload,
                error:''
            }
        case ActionTypes.FETCH_COMMENTS_FAILURE:
            return{
                ...state,
                loading:false,
                error:action.payload
            }
        case ActionTypes.ADD_COMMENTS:
            return{
                ...state,
              comments:state.comments.concat(action.payload)
            }
            
        case ActionTypes.DELETE_COMMENTS:
                return{
                    ...state,
                    comments: state.comments.filter(comment =>comment.id !==action.payload)
        
                }
        case ActionTypes.EDIT_COMMENTS:
            return{
                 ...state,
                 comments: state.comments.map(comment =>comment.id === action.payload?{
                     
                     ...comment,
                     editing:!editing
                 }:comment)
            }
            default: // need this for default case
                    return state 
    }
}
export default reducer

现在,当我单击删除时,我会在控制台上看到来自动作创建者的 ID,但该元素并未被删除 并且没有错误,这里有什么问题?

【问题讨论】:

  • 如果您在 case ActionTypes.DELETE_COMMENTS 之后执行 console.log(action),并且在 return 之前执行,您会得到什么吗?
  • @tachko 让我检查一下
  • @tachko 按照您的建议添加 console.log(action) 后,我在控制台中什么也看不到
  • 请同时添加removeComment函数的代码
  • 看起来你还没有通过connect HOC 将deleteComment 与你的组件连接起来,你只是像普通函数一样调用它。

标签: javascript html reactjs redux


【解决方案1】:

有几个结;我制作了这个简化的沙箱(模拟一个 api 调用)它应该如何工作:

https://codesandbox.io/s/wonderful-minsky-99xi4?file=/src/App.js:0-799

索引

import React from "react";
import ReactDOM from "react-dom";
import { createStore, applyMiddleware } from "redux";
import { Provider } from "react-redux";
import thunkMiddleware from "redux-thunk";
import rootReducer from "./rootReducer";
import App from "./App";

const store = createStore(rootReducer, applyMiddleware(thunkMiddleware));

const rootElement = document.getElementById("root");
ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  rootElement
);

应用程序

import React from "react";
import "./styles.css";
import { connect } from "react-redux";
import deleteRequest from "./deleteRequest";

const mapStateToProps = state => {
  return {
    comments: state.comments
  };
};

const mapDispatchToProps = {
  deleteRequest: deleteRequest
};

let App = ({ comments, deleteRequest }) => {
  const makeDeleteRequest = id => {
    deleteRequest(id);
  };

  return (
    <div className="App">
      {comments.map(comment => {
        return (
          <div key={comment.id}>
            <p>{comment.text}</p>
            <button onClick={() => makeDeleteRequest(comment.id)}>
              Delete
            </button>
          </div>
        );
      })}
    </div>
  );
};

App = connect(
  mapStateToProps,
  mapDispatchToProps
)(App);

export default App;

减速器

const initialState = {
  data: [],
  error: "",
  comments: [{ id: 1, text: "test1" }, { id: 2, text: "test2" }],
  loading: false,
  editing: false
};

function rootReducer(state = initialState, action) {
  switch (action.type) {
    case "DELETE_COMMENT":
      return {
        ...state,
        comments: state.comments.filter(comment => comment.id !== action.id)
      };
    default:
      return state;
  }
}

export default rootReducer;

异步操作

import deleteComment from "./deleteComment";

const mockAPI = new Promise(function(resolve, reject) {
  setTimeout(() => resolve("deleted"), 2000);
});

const deleteRequest = id => {
  return dispatch => {
    const makeDeleteRequest = async () => {
      await mockAPI;
      dispatch(deleteComment(id));
    };

    makeDeleteRequest();
  };
};

export default deleteRequest;

删除评论操作

export default function deleteComment(id) {
  return { type: "DELETE_COMMENT", id };
}

【讨论】:

  • 我发现问题是我没有以正确的方式将删除函数传递给我的组件,这-> function Dashboard(deleteComment){ return ()} 解决了这个问题
【解决方案2】:

看起来您实际上并没有调度操作,您只是返回了一个异步操作创建者(deleteComment 函数)。为了使您的代码正常工作,您需要首先将 redux-thunk 中间件添加到您的 redux 存储区(以便您可以使用异步操作创建器),然后在您的组件中,当您调用 deleteComponent 时,您必须包装调用使用 redux dispatch

如果您使用的是功能组件,则可以添加useDispatch 挂钩并具有以下内容:

import {useDispatch} from "react-redux";
// ...

function MyComponent() {
  const dispatch = useDispatch();
  // ...
  return <span className="delete_info" onClick={() => dispatch(deleteComment(comment.id))}>Delete</span>
}

或者您可以使用connect 函数创建a HOC 并从提供者的上下文中传递dispatch 函数:

const ConnectedComponent = connect(undefined, dispatch => ({dispatch}))(MyComponent);

function MyComponent({dispatch}) {
  return <span className="delete_info" onClick={() => dispatch(deleteComment(comment.id))}>Delete</span>;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-18
    • 2021-10-20
    • 1970-01-01
    • 2016-04-23
    • 1970-01-01
    相关资源
    最近更新 更多