Не удается прочитать свойство ‘props’ неопределенного значения при вызове отправки

#javascript #reactjs

#javascript #reactjs

Вопрос:

Я пытаюсь вызвать DeletePost функцию из

 const mapDispatchToProps = (dispatch) => ({
    DeletePost: () => dispatch(DeletePost())
});
  

Однако реакция показывает

Не удается прочитать свойство ‘props’ undefined

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);
  

Комментарии:

1. Можете ли вы поместить свой removePost внутри компонента?

2. вы имеете DeletePost в виду обработчик onClick внутри кнопки?

3. нет const removePost, поместите его внутри компонента.

4. даже после помещения removePost внутри компонента PostList он все равно возвращает Cannot read property 'props' of undefined

Ответ №1:

Потому this что в removePost функции не привязан к контексту. Вам нужно поместить его внутри PostList функции. Кроме того, в вашем коде есть три ошибки.

  1. Реквизит компонента

Функция компонента принимает props в качестве параметра. Либо используйте объект props ( props.DeletePost ), либо уничтожьте DeletePost функцию ( { DeletePost } ) из объекта props. В вашем случае вы каким-то образом пытаетесь сделать и то, и другое. Уничтожение реквизитов из реквизитов (равно props.props ).

Использовать объект props

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

Уничтожить объект props

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

Вы не передаете идентификатор сообщения отправленной DeletePost функции.

 const mapDispatchToProps = (dispatch) => ({
  // Pass id to the DeletePost functions.
  DeletePost: (id) => dispatch(DeletePost(id))
});
  
  1. Вызов removePost при каждом повторном отправке.

Реквизит события onClick принимает функцию, которая вызывается при щелчке пользователя. Но то, что вы делаете, это то, что вместо передачи onClick prop функции, вместо этого вы вызываете 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. спасибо, похоже, это работает, однако я получаю цикл.

2. 5:8000/api/posts/delete/undefined:1 DELETE http://localhost:8000/api/posts/delete/undefined 404 (Not Found)

3. предполагается, что при нажатии кнопки отображается ошибка 404, а не при ее отображении

4. Потому что вы не передаете идентификатор в функции DeletePost в mapStateToProps. Смотрите Код в ответе.

5. теперь это работает, большое спасибо, ценю вашу помощь.

Ответ №2:

Попробуйте это:

 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);
  

Комментарии:

1. я все еще получаю ошибку Cannot read property 'props' of undefined . выше this.props.DeletePost(id);

2. Кроме того, добавьте id в качестве параметра в mapDispatchToProps

3. Честно говоря, это, вероятно, сработало бы лучше, если бы вы превратили его в компонент на основе классов.

4. Не просто отправляйте код. Объясните, в чем проблема и как / почему ваше решение ее устраняет.

5. Извините, да, я как бы объяснял это в комментариях и просто решил опубликовать. В следующий раз я буду более конкретным