【问题标题】:Child component does not re-render parent after POST requestPOST 请求后,子组件不会重新渲染父组件
【发布时间】:2018-10-09 07:09:25
【问题描述】:

我想在发布新评论时重新呈现 cmets 列表。 我的父组件中的状态设置为 false,当我从子组件发布评论时,我想更新该状态。 我可以在 POST 请求之后 console.log 状态,我可以看到它从 false 变为 true,但它没有重新渲染我的父组件。 到目前为止,我只有在手动刷新页面时才能看到新评论。 我尝试使用来自父级的回调函数来更改状态,但它不起作用。 我相信这可能是一个异步问题,但我不知道如何解决它。

有什么想法吗?

家长

import React, { Component } from 'react';
import PostCommentForArticle from './PostCommentForArticle'
import axios from 'axios';
import './Comments.css'

class CommentsForArticle extends Component {
  state = {
    isPosted: false
  }
  render() {
    console.log(this.state);
    return (
      <div>
        {this.props.comments.map(comment => {
          return (
            <div class="container" id="container-comments">
              <div class="row">
                <div class="col-sm">
                  {comment.created_by}
                </div>
                <div class="col-sm">
                  {comment.created_at}
                </div>
              </div>
              <div class="row-combody">{comment.body}</div>
              <div class="row-belongsto">{comment.belongs_to}</div>
              <div class="row-votes">{comment.votes}
                <i class="far fa-thumbs-up" id="icon" onClick={() => {
                  this.incrementCommentVote(comment._id)
                  this.setState({ currCommentVote: comment.votes++ })
                }}></i>
                <i class="far fa-thumbs-down" id="icon" onClick={() => {
                  this.decrementCommentVote(comment._id)
                  this.setState({ currCommentVote: comment.votes-- })
                }}></i>
                <i class="far fa-times-circle" id="icon" onClick={() => {
                  this.deleteComment(comment._id)
                  this.setState({ isCommentDeleted: true })
                }}></i>
              </div>
            </div>
          )
        })}
        <PostCommentForArticle
          article={this.props.article}
          func={this.checkIfPosted} />
      </div>
    );
  }
  incrementCommentVote = (id) => {
    axios
      .put(
        `https://ncnewsapp.herokuapp.com/api/comments/${id}?vote=up`,
        "mytoken",
        { headers: { "Content-Type": "text/plain" } }
      )
      .then(result => console.log(result))
      .catch(e => console.log(e));
    //insert error page component
  }
  decrementCommentVote = (id) => {
    axios
      .put(
        `https://ncnewsapp.herokuapp.com/api/comments/${id}?vote=up`,
        "mytoken",
        { headers: { "Content-Type": "text/plain" } }
      )
      .then(result => console.log(result))
      .catch(e => console.log(e));
    //insert error page component
  }
  deleteComment = (data) => {
    axios
      .delete(
        `https://ncnewsapp.herokuapp.com/api/comments/${data}`,
        "mytoken",
        { headers: { "Content-Type": "text/plain" } }
      )
      .then(result => {
        console.log(result);
      })
      .catch(e => console.log(e));
  }

  checkIfPosted = (data) => {
    console.log(data);
    this.setState({ isPosted: data })
  }

}
export default CommentsForArticle;

儿童

import React, { Component } from 'react';
import Articles from './Article';
import axios from 'axios';
import './PostCommentForArticle.css';

class PostCommentForArticle extends Component {
  state = {
    userName: '',
    input: '',
  }
  render() {
    return (
      <div>
        <form id="post-comment-form">
          <div class="form-group">
            <label for="exampleInputEmail1">Username</label>
            <input type="email" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" placeholder="Enter username" value={this.state.userName} onChange={this.getUserName} />
            <small id="emailHelp" class="form-text text-muted">Post a comment.</small>
          </div>

          <div class="input-group">
            <textarea class="form-control" aria-label="With textarea" value={this.state.input} onChange={this.getUserInput}></textarea>
            <br />
          </div>
          <button type="button" class="btn btn-primary" onClick={() => this.postComment()}>Submit</button>
        </form>
      </div>
    );
  }

  getUserName = (event) => {
    this.setState({ userName: event.target.value });
  }
  getUserInput = (event) => {
    this.setState({ input: event.target.value });
  }
  postComment = () => {
    let id = this.props.article[0]._id;
    const { userName } = this.state;
    const { input } = this.state
    axios.post(`https://ncnewsapp.herokuapp.com/api/articles/${id}/comments?user=${userName}`,
      {
        "comment": `${input}`,

      })
      .then((data) => {
        this.props.func(true)
      })
  }

}
export default PostCommentForArticle;

【问题讨论】:

  • 也许你需要bind in func={this.checkIfPosted.bind(this)} ?
  • 你在哪里更新了父组件的新评论?
  • @Dario 它似乎不起作用
  • @riwu 在父级底部我有一个函数将从发布请求中接收 true,我想将状态设置为 true 并重新渲染父级
  • 如果唯一的状态变化是您不使用的布尔值,为什么重新渲染父级会显示新评论?你的父母有生命周期方法吗?

标签: javascript reactjs


【解决方案1】:

您只是在CommentsForArticle 中更新标志isPosted,但cmets 是从this.props.comments 生成的。您必须确保将新评论添加到 comments 列表中,当然是从它通过的地方,或者您可以考虑将 cmets 添加到 CommentsForArticle 的状态并添加新评论,而不是仅仅更新标志。

当您刷新页面时,您将获得那些新的 cmets,因此它会显示所有这些。

【讨论】:

    猜你喜欢
    • 2020-02-13
    • 1970-01-01
    • 2018-08-12
    • 2021-01-24
    • 2019-06-01
    • 2019-04-18
    • 2019-12-12
    • 2020-04-18
    • 1970-01-01
    相关资源
    最近更新 更多