简体   繁体   中英

this.props is not a function between parent and children components

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.

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