React:提交表单时子组件不会重新显示

时间:2019-03-20 09:37:36

标签: javascript reactjs state react-router-dom

我是React的新手,我将为您提供很多帮助。我正在使用create-react-app,react-router-dom和Express服务器。当我尝试向博客帖子(名为Details的子组件)提交评论时,它会存储在数据库中,但是该组件似乎没有更新,并且我也看不到新评论。因此,我可以看到仅在刷新页面后才提交新评论,但不提交表单。我想我没有正确设置componentDidUpdate,但我不知道如何执行此操作,因此我可以立即看到评论。

这是我的App.js:

class App extends Component {
  constructor(props) {
    super(props)
    this.state = {
      userId: null,
      username: null,
      isAdmin: false,
      isAuthed: false,
      jwtoken: null,
      posts: [],
      filtered: [],
    }
    this.handleSubmit = this.handleSubmit.bind(this)
  }

  static authService = new AuthService();
  static postService = new PostService();
  static commentService = new CommentService();

  componentDidMount() {

    const isAdmin = localStorage.getItem('isAdmin') === "true"
    const isAuthed = !!localStorage.getItem('username');

    if (isAuthed) {
      this.setState({
        userId: localStorage.getItem('userId'),
        username: localStorage.getItem('username'),
        isAdmin,
        isAuthed,
      })
    }
    this.getPosts()

  }

  componentDidUpdate(prevProps, prevState, posts) {
    if (prevState === this.state) {
      this.getPosts()
    }
  }


  handleChange(e, data) {
    this.setState({
      [e.target.name]: e.target.value
    })
  }     

  handleCommentSubmit(e, data) {

    e.preventDefault();
    e.target.reset();
    App.commentService.createComment(data)
      .then(body => {
        this.getposts()
        if (!body.errors) {
          toast.success(body.message);
        }
        else {
          toast.error(body.message);
        }
      }
      )
      .catch(error => console.error(error));

  }

  getPosts() {
    App.postService.getPost()
      .then(data => {
        this.setState({
          posts: data.posts.length? data.posts : []
        });
      }
      )
      .catch(e => this.setState({ e }))
  }

  render() {

    return (
      <Fragment>
        <Header username={this.state.username} isAdmin={this.state.isAdmin} isAuthed={this.state.isAuthed} logout={this.logout.bind(this)} />

        <Switch>

          <Route exact path="/" render={(props) => (
            <Home
              posts={this.state.posts}
              handleSearchSubmit={this.handleSearchSubmit.bind(this)}
              handleChange={this.handleSearchChange.bind(this)}
              {...props} />
          )} />

          <Route path="/posts/:id" render={(props) =>
            <Details handleSubmit={this.handleCommentSubmit.bind(this)}
              isAdmin={this.state.isAdmin}
              isAuthed={this.state.isAuthed}
              posts={this.state.posts}
              handleChange={this.handleChange}
              {...props} />} />



        </Switch>

        <Footer posts={this.state.posts} formatDate={this.formatDate} />
      </Fragment>
    );
  }
}

export default withRouter(App);

这是我的Details.js:

class Details extends Component {
  constructor(props) {
    super(props);
    this.state = {
      post: null,
      comment: null
    }
    this.handleChange = props.handleChange.bind(this);
  }

  componentDidMount() {
    const { posts, match } = this.props;

    this.setState({
      post: posts.length
        ? posts.find(p => p._id === match.params.id)
        : null,
      userId: localStorage.getItem('userId')
    })
  }

  componentDidUpdate(prevProps) {
    const { posts, match, isAuthed } = this.props;

    if (JSON.stringify(prevProps) === JSON.stringify(this.props)) {
      return;
    }

    this.setState({
      post: posts.length
        ? posts.find(p => p._id === match.params.id)
        : null
    });
  }

  render() {
    const { post } = this.state;
    const { isAdmin, isAuthed } = this.props;

    if (!post) {
      return <span>Loading post ...</span>;
    }

    return (
      <section className="site-section py-lg">

           <form onSubmit={(e)=> this.props.handleSubmit(e, this.state)} className="p-5 bg-light">

              <div className="form-group">
                <label htmlFor="message">Message</label>
                <textarea name="comment" id="message" onChange={this.handleChange} cols={30} rows={10} className="form-control" defaultValue={ ""} />
              </div>
              <div className="form-group">
                 <input type="submit" defaultValue="Post Comment" className="btn btn-primary" />
              </div>
           </form>}
       </section>
    );
  }
}

export default Details;

任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:1)

您正在犯任何新的React开发人员都会犯的错误。只要记住一件事:-

  

UI是状态的函数

因此,仅当您的状态为update时,您的UI才会更新。

提交评论后,不再重新获取所有评论,只需将您的新评论concat设为当前状态,成功提交评论后便会看到您的评论