#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
функции. Кроме того, в вашем коде есть три ошибки.
- Реквизит компонента
Функция компонента принимает 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.
}
- mapDispatchToProps
Вы не передаете идентификатор сообщения отправленной DeletePost
функции.
const mapDispatchToProps = (dispatch) => ({
// Pass id to the DeletePost functions.
DeletePost: (id) => dispatch(DeletePost(id))
});
- Вызов 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. Извините, да, я как бы объяснял это в комментариях и просто решил опубликовать. В следующий раз я буду более конкретным