Реактивный компонент не обновляется после обновления до состояния - PullRequest
0 голосов
/ 13 мая 2018

У меня есть форма для отправки нового комментария в массив комментариев this.state.comments.

В том же компоненте я хочу сделать эти новые комментарии.Но по какой-то причине мой компонент не рендерится, когда я добавляю новый комментарий.Я вижу это только когда перехожу на другую страницу и возвращаюсь к ней.Так что состояние определенно обновляется.

Ниже мой компонент, есть идеи почему?

class SinglePost extends React.Component {
    constructor(props) {
        super(props)
        const id = props.params.id - 1;
        this.state = props.messages[id];

        this.submitHandler = this.submitHandler.bind(this);
    }

    submitHandler(event) {
        event.preventDefault();
        let target = event.target;
        let comment = target.comment.value,
            user = target.user.value,
            timestamp = new Date,
            id = this.state.id,
            cmtId = this.state.comments.length ? (this.state.comments.length + 1) : 1

        this.props.postNewComment({ id, user, comment, cmtId });
    }

    render() {
        const post = this.state;
        let hour = post.timestamp.getHours();
        hour = hour > 12 ? `${hour - 12}` : hour === 0 ? '12' : `${hour}`;

        let minute = post.timestamp.getMinutes();
        minute = hour > 12 ? `${minute}pm` : `${minute}am`;

        return (
            <div>
                <Link to='/'><button className="btn btn-secondary">Back to Posts</button></Link>
                <h3>{post.title}</h3>
                <p>By: {post.user} on {hour}:{minute}</p>
                <p>{post.message}</p>
                <h4>Responses</h4>
                {post.comments.length > 0 && post.comments.map(cmt => <SingleCommentBox cmt = {cmt} key = {cmt.id}/>)}
                <div>
                    <form id="new-comment-form" onSubmit={this.submitHandler}>
                        <label className="required">Message:</label>
                        <textarea
                            className="form-control"
                            name="comment"
                            type="text"
                            required />
                        <label className="required">User:</label>
                        <input
                            className="form-control"
                            name="user"
                            type="text"
                            required />
                        <button className="btn btn-success" type="submit">Post Reply</button>
                    </form>
                </div>
            </div>
        )
    }
}

const mapStateToProps = state => {
    return {
        messages: state.messages.messages
    }
}

const mapDispatchersToProps = {
    postNewComment
}

export default connect(mapStateToProps, mapDispatchersToProps)(SinglePost)

Остальная часть моего репо .

Ответы [ 2 ]

0 голосов
/ 14 мая 2018

Я согласен с Остином в том, что вам не нужно использовать здесь государство. Ваши входы здесь не контролируются (вы не обрабатываете изменения состояния входов вашего родительского компонента).

Однако, если бы вы были, правильный способ сделать это - использовать componentWillReceiveProps.

componentWillReceiveProps(nextProps) {
  const id = nextProps.params.id - 1;
  this.setState(() => ({post: nextProps.messages[id]});
}

Еще одна рекомендация. Вы можете просто передать 'post' из функции mapStateToProps, открыв ownProps и передав идентификатор. Пример:

const mapStateToProps = (state, ownProps) => {
 return {
   post: state.messages[ownProps.id - 1)
  }
 }    

Основным преимуществом здесь является то, что вы не передаете весь массив сообщений каждому компоненту, что может ухудшить производительность, если у вас много этих компонентов на одной странице.

0 голосов
/ 13 мая 2018

Похоже, что вы инициализируете свое состояние, исходя из реквизитов в конструкторе, но никогда не обновляете его при изменении реквизитов, поэтому состояние никогда не изменится. Мне кажется, что вам вообще не нужно использовать state.

Как-то так, тогда вам и конструктор не нужен:

class SinglePost extends React.Component {

    submitHandler = (event) => {
      event.preventDefault();
      let target = event.target;
      let comment = target.comment.value,
        user = target.user.value,
        timestamp = new Date(),
        id = this.props.params.id - 1;
      const comments = this.props.messages[id].comments;
      const cmtId = comments.length ? (comments.length + 1) : 1;

      this.props.postNewComment({ id, user, comment, cmtId });
    }

    render() {
      const id = props.params.id - 1;
      const post = this.props.messages[id];
      let hour = post.timestamp.getHours();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...