更改嵌套数据的状态时,React.js无法正确呈现

时间:2018-11-19 15:28:47

标签: javascript reactjs graphql

在这里寻求帮助。

我正在实现嵌套评论功能,例如reddit。基本上我处于“状态”的数据如下所示:

post: {
  id: 'foo'
  comments: [
    { id: '1', comments: [] },
    { id: '2', comments: [ { id: '3', comments: [...]}, ... ]}
  ]
}

我的呈现数据的代码:

<Row>
  <Col md={12}>
   {post.comments.map((comment, index) => {
     return <Comment
              key={comment.id}
              comment={comment} />
    })}
  </Col>
</Row>

Comment.js:

render() {
    const comment = this.props.comment;
    return (
     <div>
      <Panel className="comment">
        <Panel.Heading className="commentHeader">
          <div>{comment.id}</div>
      </Panel.Heading>
      <Panel.Body>
        <Row>
          <h3>{comment.content}</h3>
          {comment.comments &&
            comment.comments.map((comment, index) => {
              return <Comment key={comment.id} 
                              comment={comment} />;
              })}
        </Row>
        <Row>
          <Button onClick={this.handleReply}> Reply </Button>
        </Row>
      </Panel.Body>
      </Panel>
     </div>
   );
}

我的问题是,当我在帖子的反应中添加外部评论时,效果会很好:

post: {
  id: 'foo'
  comments: [
    { id: '1', comments: [] },
    { id: '2', comments: [ { id: '3', comments: [...]}, ... ]},
    { id: 're-render works! see another comment', comments: []},
  ]
}

但是,如果新的“状态”看起来像这样,它将不会重新呈现,但是如果我重新加载页面,那就没问题了:

post: {
 id: 'foo',
 comments: [
   { id: '1', comments: [{id: 'not working unless reload page', 
                         comments: []}]},
   { id: '2', comments: [ { id: '3', comments: [...]}, ... ]},
   { id: 're-render works! see another comment', comments: []},
 ]
}

谢谢您的帮助!

2 个答案:

答案 0 :(得分:0)

我会尽力为您提供解决方案:

您尝试将子注释添加到注释中。因此,每个评论都必须有一些ID。您单击添加注释(子项或嵌套)在某些(父项)注释上。然后,获取父ID和嵌套数据,并使用一些handleCommentAdd函数执行以下操作:

const handleCommentAdd = (id, nestedData) => {
  this.setState(prevState => {
    return {
      ...prevState,
      post: {
        ...prevState.post,
        comments: prevState.post.commments.map(comment => (
          comment.id === id ?
          {
            ...comment,
            comments: comment.comments.concat(nestedData)
          } : comment
        ))
      }
    }
  })
}

编辑功能以匹配您的状态。

如果您不使用箭头功能和传播算子:

const handleCommentAdd = function(id, nestedData) {
  this.setState(function(prevState) {
    return Object.assign(
      {},
      prevState,
      {post: Object.assign(
        {},
        prevState.post,
        {comments: prevState.post.comments.map(function(comment) {
          comment.id === id ?
          Object.assign(
            {},
            comment,
            {comments: comment.comments.concat(nestedData)}
          ) : comment
        })}
      )}
    )
  })
}

答案 1 :(得分:0)

在数据更新(现有的,已安装的)组件接收到新的道具之后-默认情况下,此功能(与状态更改相反),重新渲染不会产生结果。

假设数据已更新且更改正确传播(开发工具中的更新道具)...您应该使用shouldComponentUpdate-对prop.comment中的差异返回true(浅比较就足够了)-仅此而已