繁体   English   中英

获取错误 TypeError:无法使用 React/Redux 操作读取未定义的属性“id”

[英]Getting error TypeError: Cannot read property 'id' of undefined using React/Redux action

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

直接错误来自下面的 Post 组件,从 catch 块中的this.props.deleteRecord向下。

我也在使用 turbo,这就是我如何制作 deleteRequest 并存储数据。 如果您需要参考这里是文档。 https://www.turbo360.co/docs

减速器:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM