Реагируйте: дочерний компонент не рендерится при отправке формы - PullRequest
0 голосов
/ 20 марта 2019

Я новичок в React и буду очень признателен за любую помощь.Я использую create-реагировать-приложение, реагировать-маршрутизатор-дом и экспресс-сервер.Когда я пытаюсь отправить комментарий к сообщению в блоге (дочерний компонент с именем 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 Ответ

1 голос
/ 20 марта 2019

Вы делаете ошибку, которая будет допущена любым новым разработчиком React.Просто запомните одну вещь: -

Пользовательский интерфейс является функцией состояния

Таким образом, ваш пользовательский интерфейс будет обновляться только при обновлении вашего состояния.

После отправки комментария не загружайте все ваши комментарии снова, просто concat ваш новый комментарий в текущем состоянии, и вы увидите свой комментарий, как только вы успешно отправите его

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...