如何有效地传递相同的" prop"每个无状态演示组件?

时间:2016-03-12 11:36:49

标签: javascript reactjs

我看起来像是非DRY代码的简单常见情况 - 我希望有一种方法可以避免这种情况。

我有一个页面来根据这样的路径呈现有关对象的信息:

  <Route path="project/:projectid" component={ProjectDetails}/>

所以...项目ID&#39;来自React Router的prop,每个无状态表示组件都需要生成的项目对象:

class ProjectDetails = ({project}) => {
   render() {
      return (
         <div className="project-details-page container-fluid">
             <HomeLeftBar/> 
             <div className="col-md-10">
                 <ProjectHeaderBar project={project}/>
             </div>
             <div className="project-centre-pane col-md-7">
                 <ProjectActions project={project}/>
                 <ProjectDescription project={project}/>
                 <ProjectVariations project={project}/>
             </div>
             <div className="project-right-bar col-md-3">
                 <ProjectContacts project={project}/>
                 <ProjectCosting project={project}/>
             </div>
         </div>
      )
   }
}

export default connect(
   state => ({project: state.projects[state.router.params.projectid]})
)(ProjectDetails)

我应该如何清理它,所以我不必将project传递给每个组件?

我至少注意到了几个类似问题thisthis。但虽然他们的头衔很相似,但他们的细节并非如此。他们似乎对更具体的情况提出更高级的问题。

2 个答案:

答案 0 :(得分:3)

对我来说,通过道具从顶部传递数据是将数据输入叶子组件的最清晰的方法,所以我认为你在这里做的很好。

看起来不干净的一点就是你将整个project对象传递给每个组件但是一眼就看出每个组件都只负责渲染一部分那个project对象。

仅传递每个组件所需的project分支将使数据和视图之间的关系更加清晰。

<ProjectContacts project={project.contracts}/> <ProjectCosting project={project.costing}/>

反过来我认为这会让整个组件感觉更清洁:

class ProjectDetails = ({project: { costings, description, variations, title, actions, contacts} }) => {
   render() {
      return (
         <div className="project-details-page container-fluid">
             <HomeLeftBar/> 
             <div className="col-md-10">
                 <ProjectHeaderBar title={title}/>
             </div>
             <div className="project-centre-pane col-md-7">
                 <ProjectActions actions={actions}/>
                 <ProjectDescription description={description}/>
                 <ProjectVariations variations={variations}/>
             </div>
             <div className="project-right-bar col-md-3">
                 <ProjectContacts contacts={contacts}/>
                 <ProjectCosting costings={costings}/>
             </div>
         </div>
      )
   }
}

答案 1 :(得分:1)

我假设你正在使用react-router。你可以这样做:

        <Router history={history}>
            <Route path="project/:projectId">
                <Route path="participants" component={Participants} />
                <Route path="progress" component={Progress}/>
            </Route>
        </Router>

<Route path="project/:projectId">的所有孩子都有this.props.params.projectId可用。例如,参与者组件的网址为"project/:projectId/participants",因此projectId是呈现参与者时的参数。

此外,如果项目详细信息应在所有页面上以相同方式呈现,则可以将Route上的组件添加到“project /:projectId”,该组件负责呈现项目详细信息。 (该组件将以this.props.children的形式接收参与者或进度,您必须在新组件中进行呈现。)