Почему ComponentShouldUpdate предотвращает рендеринг комментариев? - PullRequest
0 голосов
/ 27 сентября 2018

Я реализовал componentShouldUpdate в приведенном ниже коде, чтобы попытаться повысить производительность.Эта цель была достигнута, но теперь комментарии не отображаются.Консоль браузера показывает, что все уже получено.Также есть div, который отображает количество комментариев и также обновляется.

            class ProposalDetail extends React.Component {
                      constructor(props) {
                        super(props);
                        this.state = {
                          sortedComments: []
                        };
                      }
                      componentDidUpdate(prevProps) {
                        if((!prevProps.proposal || Object.keys(prevProps.proposal).length === 0 ) &&
                          this.props.proposal && Object.keys(this.props.proposal).length > 0 &&
                          this.props.proposal.status === 4 ){
                          prevProps.onFetchProposalVoteStatus(prevProps.token);
                        }
                        this.handleUpdateOfComments(prevProps, this.props);
                      }
                      shouldComponentUpdate(nextProps, nextState) {
                        console.log('thisProps', this.props.comments)
                        console.log('nextProps', nextProps.comments)
                        if (this.props.comments === nextProps.comments) {
                            return true
                        }
                        else {
                            return false
                        }
                      }
                      componentDidMount() {
                        this.props.onFetchLikedComments(this.props.token);
                      }
                      componentWillUnmount() {
                        this.props.resetLastSubmittedProposal();
                      }
                      handleUpdateOfComments = (currentProps, nextProps) => {
                        let sortedComments;

                        if(!nextProps.comments || nextProps.comments.length === 0) {
                          return;
                        }
                        // sort option changed
                        if(currentProps.commentsSortOption !== nextProps.commentsSortOption) {
                          sortedComments = updateSortedComments(
                            this.state.sortedComments,
                            nextProps.commentsSortOption
                          );
                        }

                        // new comment added
                        if(currentProps.comments.length !== nextProps.comments.length) {
                          const isEmpty = currentProps.comments.length === 0;
                          const newComments = isEmpty ?
                            nextProps.comments :
                            [nextProps.comments[nextProps.comments.length - 1]]
                              .concat(this.state.sortedComments);
                          sortedComments = updateSortedComments(
                            newComments,
                            currentProps.commentsSortOption,
                            nextProps.commentsvotes,
                            isEmpty
                          );
                        }

                        // usernames aren't fully merged into comments
                        const commentWithoutAnUsername = comments => comments.filter(c => !c.username)[0];
                        if (commentWithoutAnUsername(this.state.sortedComments) && !commentWithoutAnUsername(nextProps.comments)) {
                          sortedComments = updateSortedComments(
                            nextProps.comments,
                            currentProps.commentsSortOption,
                            nextProps.commentsvotes,
                            false
                          );
                        }

                        // commentsvotes changed
                        if(nextProps.commentsvotes && !isEqual(currentProps.commentsvotes, nextProps.commentsvotes)) {
                          const updatedComments = getUpdatedComments(nextProps.commentsvotes, nextProps.comments);
                          const newComments = mergeNewComments(this.state.sortedComments, updatedComments);
                          sortedComments = updateSortedComments(
                            newComments,
                            currentProps.commentsSortOption,
                            nextProps.commentsvotes,
                            false
                          );
                        }

                        // comment gets censored
                        if(nextProps.censoredComment && !isEqual(currentProps.censoredComment, nextProps.censoredComment)) {
                          sortedComments = updateSortedComments(
                            nextProps.comments,
                            currentProps.commentsSortOption,
                            nextProps.commentsvotes,
                            true
                          );
                        }

                        if(sortedComments) {
                          this.setState({ sortedComments });
                          console.log('setState', this.state.sortedComments);

                        }
                      }
                      render() {
                        const {
                          isLoading,
                          proposal,
                          token,
                          error,
                          markdownFile,
                          otherFiles,
                          onFetchData,
                          ...props
                        } = this.props;
                        console.log(this.props);
                        const comments = this.state.sortedComments;
                        return (
                          <div className="content" role="main">
                            <div className="page proposal-page">
                              {error ? (
                                <Message
                                  type="error"
                                  header="Proposal not found"
                                  body={error} />
                              ) : (
                                <Content  {...{
                                  isLoading,
                                  error,
                                  bodyClassName: "single-page comments-page",
                                  onFetchData: () => onFetchData(token),
                                  listings: isLoading ? [] : [
                                    {
                                      allChildren: [{
                                        kind: "t3",
                                        data: {
                                          ...proposalToT3(proposal, 0).data,
                                          otherFiles,
                                          selftext: markdownFile ? getTextFromIndexMd(markdownFile) : null,
                                          selftext_html: markdownFile ? getTextFromIndexMd(markdownFile) : null
                                        }
                                      }]
                                    },
                                    { allChildren: commentsToT1(comments) }
                                  ],
                                  ...props
                                }} />
                              )}
                            </div>
                          </div>
                        );
                      }
                    }

                    export default ProposalDetail;

Ответы [ 2 ]

0 голосов
/ 27 сентября 2018

Это не componentShouldUpdate, а shouldComponentUpdate

shouldComponentUpdate в основном решает, требует ли компонент повторного рендеринга или нет.Этот метод возвращает только true или false.По умолчанию этот метод возвращает значение true, что означает, что компонент должен рендериться всегда, когда происходит setState или получены реквизиты независимо от состояния и сравнения реквизитов.

Таким образом, в вашем случае вы неправильно сравниваете комментарии в shouldComponentUpdate.Вы должны возвращать true только в том случае, если текущие реквизиты и предыдущие реквизиты не равны, иначе false, но вы проверяете наоборот.

Приведенный ниже код будет работать

     shouldComponentUpdate(nextProps, nextState) {
                    console.log('thisProps', this.props.comments)
                    console.log('nextProps', nextProps.comments)
                    if (JSON.stringify(this.props.comments) !== JSON.stringify(nextProps.comments)) {
                        return true
                    }
                    else {
                        return false
                    }
                  }
0 голосов
/ 27 сентября 2018

Попробуйте:

JSON.stringify(this.props.comments) === JSON.stringify(nextProps.comments)

Этот грязный хак может помочь.

Проблема в том, что вы не можете сравнить два массива в такомкак вы делаете.

...