React Router是否导致我的组件渲染两次?

时间:2019-08-31 20:09:05

标签: javascript reactjs react-redux react-router

背景

我有一个物品清单。如果单击某个项目下的详细信息链接,则会转到该页面,在该页面上您可以阅读和添加有关该特定项目的注释。当前,评论组件同时在index pageitem details page上呈现。它只能在后者上呈现。

您能帮我找出原因吗?

问题排查

我检查了路线以及“注释”和“注释”组件,但未发现任何明显的错误。我看到this post关于渲染组件两次,但是我的情况有所不同,因为我必须使用render=传递道具。

我会承认,我从未尝试过构建这样的路线,所以也许我没有正确处理它。一个问题是此列表底部的第二个。

路线

  render(){
    return(
      <div>
        <Switch>
          <Route exact path='/' render={(routerProps) => <Programs {...routerProps} programs={this.props.programs}/>} /> />
          <Route exact path='/programs' render={(routerProps) => <Programs {...routerProps} programs={this.props.programs} />} />
          <Route path='/programs/new' render={(routerProps) => <ProgramInput {...routerProps}/>}/>
          <Route path='/programs/:id' render={(routerProps) => <Program {...routerProps} programs={this.props.programs}/>}/>
          <Route exact path='/programs/:id/comments' render={(routerProps) => <Program {...routerProps} program={this.props.program}/>}/>
          <Route exact path='/watchlist' render={(routerProps) => <Program {...routerProps} programs={this.props.programs} />} />
        </Switch>
      </div>
    )
  }

CommentsContainer

class CommentsContainer extends React.Component {
  render(){
    return(
      <div>
        <Comments comments={this.props.program && this.props.program.comments}/>
      </div>
    )
  }
}

export default CommentsContainer

程序(在其中呈现CommentsContainer的程序)

I took out some of the Card code for brevity. There is More link inside the card that takes you to the item page. That part works fine.

return(
        <Fragment>
          <Grid.Column>
            <Card as='div'>
             </Card>
          </Grid.Column>

          <CommentsContainer program={program}/>

        </Fragment>
      )
    }

评论

const Comments = (props) => {
  // console.log(props.comments && props.comments.map(comment => console.log(comment))
  return(
    <Comment.Group>


      {props.comments && props.comments.map(comment => <CommentCard key={comment.id} comment={comment}/>)}


    </Comment.Group>
  )
}

export default Comments

ComentCard 我认为问题不在这里,但是如果您需要查看文件,则使用here's a link

后端

我在后端使用Rails API。 Here is a link to my comments_controller if you want to take a peek.

谢谢您的时间和建议!

3 个答案:

答案 0 :(得分:1)

如果您只想在有评论时显示CommentsContainer,则可以将其呈现的行替换为:

{program.comments && <CommentsContainer program={program}/>}

答案 1 :(得分:1)

正如Matt Oestreich先前指出的那样,在渲染程序组件时,总是会渲染注释。程序(多个)组件基本上是一个由程序组件组成的列表。因此,在渲染程序组件时,总是将带有注释组件的CommentsContainer呈现。

因此,也许您可​​以制作另一个组件,在其中包含CommentsContainer的ProgramDetails组件。在程序组件中,您可以链接到ProgramDetails组件。我认为这可以防止在程序(复数)中呈现的注释被呈现。

答案 2 :(得分:0)

这确实是路线问题。我的/和我的props.match路由都在显示我的CommentsContainer,因为我需要添加一个三进制来从本质上过滤掉那些路由。

我在“卡”组件之后的“程序(多个)”组件中添加了此代码。它使用/programs检查要渲染的路由是否不是/和NOT /programs/:id。当该语句评估为true时,CommentsContainer和关联的注释将在{this.props.match.url !== '/programs' && this.props.match.url !== '/'? <CommentsContainer program={program}/> : null} 上呈现。如果这些语句中的任何一条评估为true,则它不会呈现任何内容。

props.match

由于我只通过了 Programs.js 文件中的routerProps,因此我不得不将{props.programs && props.programs.map((program) => <Program key={program.name} program={program} match={props.match}/>)} 从“程序”传递到我的“程序”组件(该组件渲染卡和CommentContainer)。这样做可以使上面的三进制起作用。

BaseSite