调用分派时无法读取未定义的属性“ props”

时间:2019-04-12 21:26:15

标签: javascript reactjs

我正在尝试从

调用DeletePost函数
const mapDispatchToProps = (dispatch) => ({
    DeletePost: () => dispatch(DeletePost())
});

但是,反应正在显示

  

无法读取未定义的属性“ props”

PostList.js

import {connect} from 'react-redux';
import {DeletePost} from '../actions/';
const Styles = {
    myPaper: {
        margin: '20px 0px',
        padding: '20px'
    }
}
const removePost = (id) => {
  // showing error below this line cannot read props
  this.props.DeletePost(id);
}

const PostList = ({props, posts}) => {

    return (
        <div>
            {posts.map((post, i) => (
                <Paper key={i} style={Styles.myPaper}>
                    <Typography variant="h6" component="h3">
                        {post.title}
                    </Typography>
                    <Typography component="p">
                        {post.post_content}
                        <h5>
                            by: {post.username}</h5>
                        <h5>
                            {moment(post.createdAt).calendar()}</h5>
                    </Typography>
                    <Button
                        variant="outlined"
                        color="primary"
                        type="submit"
                        onClick={removePost(post.id)}>
                        Remove
                    </Button>
                </Paper>
            ))}
        </div>
    )
};
const mapDispatchToProps = (dispatch) => ({
    DeletePost: () => dispatch(DeletePost())
});
export default connect(null, mapDispatchToProps)(PostList);

2 个答案:

答案 0 :(得分:3)

因为this函数中的removePost未绑定到上下文。您需要将其放在PostList函数中。另外,您的代码中存在三个错误。

  1. 道具道具

Component函数采用props作为参数。使用props对象(props.DeletePost),或从props对象破坏DeletePost函数({ DeletePost })。在您的情况下,您正试图同时做到这两者。从道具(等于props.props)破坏道具。

使用道具对象

const PostList = (props) => {
  // use props.DeletePost() and props.posts.
}

破坏道具对象

const PostList = (props) => {
  // use DeletePost() and posts.
}
  1. mapDispatchToProps

您没有将帖子ID传递给分派的DeletePost函数。

const mapDispatchToProps = (dispatch) => ({
  // Pass id to the DeletePost functions.
  DeletePost: (id) => dispatch(DeletePost(id))
});
  1. 每次重新渲染时都调用removePost。

onClick事件道具具有一个在用户单击时调用的功能。但是您正在做的是,不是在传递onClick属性,而是在调用removePost函数。 remove函数将依次返回undefined,单击按钮时不执行任何操作。但是,当您在渲染时调用removePost函数时,将调度DeletePost操作。我认为该操作将更新状态,这将导致组件重新呈现。而且您陷入了一个inifite循环中,因为removePost将再次被调用。

要解决此问题。 removePost函数应该返回一个新函数。从removePost返回的函数现在将分配给onClick道具,并在单击按钮时调用。

示例

  const removePost = (id) => () => {
    DeletePost(id);
  }


const PostList = ({DeletePost, posts}) => {
  // Return a new function. Otherwise the DeletePost action will be dispatch each time the Component rerenders.
  const removePost = (id) => () => {
    DeletePost(id);
  }

  return ( ... )
}

const mapDispatchToProps = (dispatch) => ({
  // Pass id to the DeletePost functions.
  DeletePost: (id) => dispatch(DeletePost(id))
});

答案 1 :(得分:0)

尝试一下:

const PostList = ({props, posts}) => {
    const removePost = (id) => {
    // showing error below this line cannot read props
    this.props.DeletePost(id);
   }
    return (
        <div>
            {posts.map((post, i) => (
                <Paper key={i} style={Styles.myPaper}>
                    <Typography variant="h6" component="h3">
                        {post.title}
                    </Typography>
                    <Typography component="p">
                        {post.post_content}
                        <h5>
                            by: {post.username}</h5>
                        <h5>
                            {moment(post.createdAt).calendar()}</h5>
                    </Typography>
                    <Button
                        variant="outlined"
                        color="primary"
                        type="submit"
                        onClick={removePost(post.id)}>
                        Remove
                    </Button>
                </Paper>
            ))}
        </div>
    )
};
const mapDispatchToProps = (dispatch) => ({
    DeletePost: (id) => dispatch(DeletePost(id))
});
export default connect(null, mapDispatchToProps)(PostList);