javascript - 出现错误 TypeError : Cannot read property 'id' of undefined using React/Redux action

标签 javascript reactjs redux

我正在使用react/redux,并且在使用操作调用deleteRequest之后发生错误。 reducer 从数组中删除该项目,我认为这就是发生这种情况的原因,但我应该更改位置,以便它不再呈现此页面。

直接错误来自下面的 Post 组件,位于 catch block 中的 this.props.deleteRecord 中。

我还使用turbo,这是我发出删除请求和存储数据的方式。如果您需要引用这里的文档。 https://www.turbo360.co/docs

reducer :

import constants from '../constants';

const initialState = {
  all: null
};

export default (state = initialState, action) => {
  switch (action.type) {
    case constants.POST_CREATED:
      return {
        ...state,
        all: state.all.concat(action.data),
        [action.data.id]: action.data
      };

    case constants.RECORD_UPDATED:
      return {
        ...state,
        [action.data.id]: action.data,
        all: all.map(item => (item.id === action.data.id ? action.data : item))
      };

    case constants.RECORD_DELETED:
      const newState = {
        ...state,
        all: state.all.filter(item => item.id !== action.data.id)
      };
      delete newState[action.payload.id];

      return newState;

    case constants.FETCH_POSTS:
      const sortedData = action.data.sort((a, b) => {
        return new Date(b.timestamp) - new Date(a.timestamp);
      });
      return { ...state, all: sortedData };

    case constants.FETCH_POST:
      return { ...state, [action.data.id]: action.data };

    default:
      return state;
  }
};

组件:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
import swal from 'sweetalert2/dist/sweetalert2.all.min.js';

import actions from '../../actions';
import { DateUtils } from '../../utils';
import { Reply } from '../containers';
import { UpdateRecord } from '../view';

class Post extends Component {
  constructor() {
    super();
    this.state = {
      editShow: false
    };
  }

  componentDidMount() {
    const { id } = this.props.match.params;
    if (this.props.posts[id] != null) {
      return;
    }
    this.props
      .getRecord(id)
      .then(() => {})
      .catch(err => {
        console.log(err);
      });
  }

  updateRecord(params) {
    const { id } = this.props.match.params;
    const post = this.props.posts[id];
    const { currentUser } = this.props.user;
    if (post.profile.id !== currentUser.id) {
      swal({
        title: 'Oops...',
        text: 'Must be owner of post',
        type: 'error'
      });
      return;
    }

    this.props
      .updateRecord(post, params)
      .then(response => {
        swal({
          title: 'Success',
          text: `${currentUser.username} Your post has been updated!`,
          type: 'success'
        });
      })
      .catch(err => {
        console.log(err);
      });
  }

  deleteRecord() {
    const { id } = this.props.match.params;
    const post = this.props.posts[id];
    const { currentUser } = this.props.user;

    if (currentUser.id !== post.profile.id) {
      swal({
        title: 'Oops...',
        text: 'Must be owner of post',
        type: 'error'
      });
      return;
    }

    this.props
      .deleteRecord(post)
      .then(() => {
        this.props.history.push('/');

        swal({
          title: 'Post Delete',
          text: 'Please create a new post',
          type: 'success'
        });
      })
      .catch(err => {
        console.log(err);
      });
  }

  render() {
    const { id } = this.props.match.params;
    const post = this.props.posts[id];
    const { currentUser } = this.props.user;
    if (post == null) {
      return <div />;
    }

    return (
      <div>
        <div className="jumbotron">
          <h1 className="display-3">{post.title}</h1>
          <div className="row" style={{ marginBottom: '25px' }}>
            <img className="img-fluid mx-auto" src={`${post.image}`} style={{ maxHeight: '400px' }} />
          </div>
          <p className="lead">{post.text}</p>
          <hr className="my-4" />
          {post.video == undefined ? null : (
            <div className="row justify-content-center">
              <div className="col-8">
                <div className="lead" style={{ marginBottom: '25px' }}>
                  <div className="embed-responsive embed-responsive-16by9">
                    <video style={{ background: 'black' }} width="800" controls loop tabIndex="0">
                      <source src={post.video} type={post.videoType} />
                      Your browser does not support HTML5 video.
                    </video>
                  </div>
                </div>
              </div>
            </div>
          )}
          <div className="lead">
            <Link to={`/profile/${post.profile.id}`}>
              <button className="btn btn-secondary btn-lg">{post.profile.username}</button>
            </Link>
            <p style={{ marginTop: '10px' }}>{DateUtils.relativeTime(post.timestamp)}</p>
          </div>
          {currentUser.id !== post.profile.id ? null : (
            <div className="row justify-content-end">
              <div className="col-md-2">
                <button
                  onClick={() => {
                    this.setState({ editShow: !this.state.editShow });
                  }}
                  className="btn btn-success"
                >
                  Edit
                </button>
              </div>
              <div className="col-md-2">
                <button onClick={this.deleteRecord.bind(this)} className="btn btn-danger">
                  Delete
                </button>
              </div>
            </div>
          )}
        </div>
        {this.state.editShow === false ? null : (
          <div>
            <UpdateRecord onCreate={this.updateRecord.bind(this)} currentRecord={post} />
          </div>
        )}
        <div>
          <Reply postId={post.id} />
        </div>
      </div>
    );
  }
}

const stateToProps = state => {
  return {
    posts: state.post,
    user: state.user
  };
};

const dispatchToProps = dispatch => {
  return {
    getRecord: id => dispatch(actions.getRecord(id)),
    updateRecord: (entity, params) => dispatch(actions.updateRecord(entity, params)),
    deleteRecord: entity => dispatch(actions.deleteRecord(entity))
  };
};

export default connect(stateToProps, dispatchToProps)(Post);

最佳答案

看这里

case constants.RECORD_DELETED:
  const newState = {
    ...state,
    all: state.all.filter(item => item.id !== action.data.id)
  };
  delete newState[action.payload.id];

  return newState;

您在过滤时使用 action.data,在从对象中删除时使用 action.payload

关于javascript - 出现错误 TypeError : Cannot read property 'id' of undefined using React/Redux action,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46899667/

相关文章:

javascript - 有什么方法可以延迟执行 JavaScript 导出语句吗?

javascript - jquery中options和originalOptions的区别

javascript - 如何在 AngularJS 中迭代对象数组并打印键

Javascript 获取文件名不起作用

javascript - 选择特定文件类型时切换额外输入

reactjs - 将自定义 Prop 添加到自定义组件

javascript - AngularJS - 使用 $http 和 debounce 处理动态搜索

javascript - Material-ui 中基于类的样式

javascript - Provider 中的无效 Prop child

javascript - 如何在 reactjs 中删除导入的 css