为什么ComponentShouldUpdate阻止渲染注释?

时间:2018-09-27 17:37:11

标签: javascript reactjs lifecycle

我在下面的代码中实现了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 :(得分:1)

它不是componentShouldUpdate,而是应当componentUpdate

shouldComponentUpdate基本上决定组件是否需要重新渲染。此方法仅返回true或false。默认情况下,此方法返回true,这意味着无论何时发生setState或接收到props,无论状态和props比较如何,组件都需要始终重新渲染。

因此,在您的情况下,您应该在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
                    }
                  }

答案 1 :(得分:0)

尝试一下:

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

肮脏的黑客 可以提供帮助。

问题是您无法以这种方式比较两个数组。