React:子组件在提交表单时不会重新呈现

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了React:子组件在提交表单时不会重新呈现相关的知识,希望对你有一定的参考价值。

我是React的新手,我会提供很多帮助。我正在使用create-react-app,react-router-dom和express server。当我尝试向博客帖子(名为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;

任何帮助都感激不尽!

答案

您正在犯一个由任何新的React开发人员完成的错误。记住一件事: -

UI是状态的函数

因此,只有在状态更新时才会更新UI。

提交评论后,请不要再次获取所有评论,只需concat您对当前状态的新评论,一旦您成功提交,您将看到您的评论

以上是关于React:子组件在提交表单时不会重新呈现的主要内容,如果未能解决你的问题,请参考以下文章

React - 登录提交按钮以呈现新页面

关于antd如何在表单外点击触发表单验证的问题

react多组表单同事提交怎么分组

我的提交和编辑表单的 React 模态组件不会关闭?

在 React 中使用父组件中的按钮提交表单

更新 redux 状态/提交表单时页面重新加载