After setup a simple post component, it would be cool to be able to get the comments from the post.
import React, { Component } from "react";
import axios from "axios";
import Comments from "../components/comments";
class Post extends Component {
constructor(props) {
super(props);
this.state = {
comments: [],
};
}
componentDidMount() {
this.getComments();
}
getComments() {
return axios
.get("/posts/" + this.props.match.params.id + "/comments")
.then(result => this.setState({ comments: result.data.comments }))
.catch(error =>
this.setState({
error
})
);
}
render() {
return (
<div>
<h2>Comments</h2>
<Comments />
</div>
);
}
}
export default Post;
so after, place a comment component to get the post comments in the logs start to show
TypeError: this.props.getComments is not a function
So, is not possible to pass props from function? someone has any idea why this issue happen?
the comments component
import Comment from "./comment";
import axios from "axios";
import Post from "../screens/posts";
class Comments extends Component {
constructor(props) {
super(props);
this.state = {
comments: [],
error: ""
};
this.load = this.load.bind(this);
}
componentDidMount() {
this.load();
}
load() {
return this.props.getComments().then(comments => {
this.setState({ comments });
return comments;
});
}
render() {
return (
<div>
{this.state.comments.map(comment => (
<Comment key={comment.id} comment={comment} />
))}
</div>
);
}
}
export default Comments;
You are not passing the function to Comments as a prop.
You must pass the function as a prop like this:
<Comments getComments={this.getComments} />
It's hard to tell, but you seem to have some wires crossed with when to use props
and when to use state
.
I'm going to have a go at actually fixing this to get it closer to your intended solution, rather than just making it not crash (I'm also going to try not to deviate too much from your style).
Post.js
import React, { Component } from "react";
import axios from "axios";
import Comments from "../components/comments";
class Post extends Component {
constructor(props) {
super(props);
this.state = {
comments: undefined,
loading: false,
error: undefined
};
}
componentDidMount() {
this.loadComments();
}
// This doesn't return anything, it doesn't need to as the result is getting put into state
loadComments() {
this.setState({
comments: undefined,
loading: true,
error: undefined
};
axios.get("/posts/" + this.props.match.params.id + "/comments")
.then(result => this.setState({
comments: result.data.comments,
loading: false,
error: undefined
}))
.catch(error => this.setState({
loading: false,
comments: undefined,
error
}));
}
// Some loading and error states added
// Note the passing of comments as a prop to Comments
render() {
return (
<div>
<h2>Comments</h2>
{this.state.loading && <div>Loading...</div>}
{this.state.error && <div>There was an error - {this.state.error}</div>}
{this.state.comments && <Comments comments={this.state.comments} />}
</div>
);
}
}
export default Post;
Comments.js
import React, { Component } from "react";
import Comment from "./comment";
// No longer needs to do any loading or keep any state of its own (it uses props instead), this could be simplified into an Functional Stateless Component (FSC) now if you wanted to.
class Comments extends Component {
render() {
return (
<div>
{this.props.comments.map(comment => (
<Comment key={comment.id} comment={comment} />
))}
</div>
);
}
}
export default Comments;
You are not passing the getComments props in your Post
render method. Pass them like so:
<Comments getComments={this.getComments} />
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.