Search code examples
reactjsmongodbexpressnodes

Having trouble updating component state in ReactJS


I'm relatively new to ReactJS.

I'm having trouble updating a components state. When I console log the results of my api fetch, the object is there and not undefined.

This is the code I'm working with:

  class Article extends Component {
  state = { post: {} };

  componentDidMount() {
    const id = this.props.match.params.id;
    fetch(`/posts/${id}/`)
      .then(res => res.json())
      .then(post => {
        this.setState(post);
        console.log(post);
      });
  }

  renderContent() {
    if (
      Object.entries(this.state.post).length === 0 &&
      this.state.post.constructor === Object
    ) {
      return <p>Blog does not exist sadly</p>;
    } else {
      return (
        <div>
          {" "}
          {Object.keys(this.state.post).map(p => (
            <div
              style={{ maxWidth: "auto", textAlign: "centre" }}
              key={this.state.post[p].title}
            >
              <Header heading={this.state.post[p].title} />
              <div
                style={{ padding: "40px" }}
                dangerouslySetInnerHTML={{ __html: this.state.post[p].content }}
              />
            </div>
          ))}
        </div>
      );
    }
  }

  render() {
    return (
      <div>
        {this.renderContent()}
        <Footer />
      </div>
    );
  }
}

export default Article;

This is the results of an api fetch:

{"_id":"5ce1ae8fc915dc48d13d7c1c","title":"example title","content":"example content"}

Express code that returns the results of the MongoDB query:

router.get("/posts/:id", function(req, res, next) {
  MongoClient.connect("mongodb://localhost:27017/express", function(
    err,
    client
  ) {
    if (err) throw err;

    var db = client.db("express");
    var id = parseInt(req.params["id"]);
    db.collection("posts")
      .find()
      .sort({ _id: 1 })
      .toArray(function(err, result) {
        if (err) throw err;
        if (result.length > 0) {
          res.send(result[id]);
        } else {
          res.status(403);
        }
      });
  });
});

This only seems to happen when working with a single result fetch and not when I'm fetching an array of objects.

update:

tried calling console.log(this.state) instead of calling console.log(this.state.post and get this back:

{post: {}, _id: "5ce1ae8fc915dc48d13d7c1c", title: "example title", content: "example content"}

so seems like it is there but I'm updating the state wrong?


Solution

  • Can you double-check if you are using the correct function to set state?

    It should be this.setState({ post }), not this.setState(post)

    class Article extends Component {
      state = { post: null };
    
      componentDidMount() {
        const id = this.props.match.params.id;
        fetch(`/posts/${id}/`)
          .then(res => res.json())
          .then(post => {
            this.setState({ post }, console.log(this.state.post));
          });
      }
    
      renderContent() {
        const { post } = this.state
        if (!post) {
          return <p>Blog does not exist sadly</p>;
        } else {
          return (
            <div>
              {" "}
              <div
                  style={{ maxWidth: "auto", textAlign: "centre" }}
                  key={post.title}
                >
                  <Header heading={post.title} />
                  <div
                    style={{ padding: "40px" }}
                    dangerouslySetInnerHTML={{ __html: post.content }}
                  />
                </div>
            </div>
          );
        }
      }
    
      render() {
        return (
          <div>
            {this.renderContent()}
            <Footer />
          </div>
        );
      }
    }
    
    export default Article;