简体   繁体   English

React Router 4 将道具传递给动态组件

[英]React Router 4 Pass props to dynamic component

I have a list of doctors and I am trying to dynamically render a details page when selected.我有一个医生列表,我试图在选择时动态呈现详细信息页面。 I see most people recommend to pass props through the Route component, something like this:我看到大多数人建议通过 Route 组件传递道具,如下所示:

<Route path={`${match.url}/:name`}
  component={ (props) => <DoctorView doctor={this.props.doctors} {...props} />}
  />

Though I'm not clear on where I should be executing this.虽然我不清楚我应该在哪里执行这个。 I tried it in DoctorList and DoctorItem but that didn't work.我在 DoctorList 和 DoctorItem 中尝试过,但是没有用。 So I've set the Route in the App component, and I am able select a doctor, which then renders the DoctorView component and display the match.params prop just fine.所以我在 App 组件中设置了 Route,我可以选择一个医生,然后渲染 DoctorView 组件并显示 match.params 道具就好了。 But how do I get the selected doctor data to DoctorView?但是如何将选定的医生数据获取到 DoctorView? I'm probably making this harder than it should be.我可能让这比它应该更难。 Here is my code:这是我的代码:

App.jsx应用程序.jsx

const App = () => {
  return (
    <div>
      <NavigationBar />
      <FlashMessagesList />
      <Switch>
        <Route exact path="/" component={Greeting} />
        <Route path="/signup" component={SignupPage} />
        <Route path="/login" component={LoginPage} />
        <Route path="/content" component={requireAuth(ShareContentPage)} />
        <Route path="/doctors" component={requireAuth(Doctors)} />
        <Route path="/doctor/:name" component={requireAuth(DoctorView)} />
      </Switch>
    </div>
  );
}

DoctorList.jsx DoctorList.jsx

class DoctorList extends React.Component {
  render() {
    const { doctors } = this.props;
    const linkList = doctors.map((doctor, index) => {
      return (
        <DoctorItem doctor={doctor} key={index} />
      );
    });

    return (
      <div>
        <h3>Doctor List</h3>
        <ul>{linkList}</ul>
      </div>
    );
  }
}

DoctorItem.jsx DoctorItem.jsx

const DoctorItem = ({ doctor, match }) => (
  <div>
    <Link
      to={{ pathname:`/doctor/${doctor.profile.first_name}-${doctor.profile.last_name}` }}>
      {doctor.profile.first_name} {doctor.profile.last_name}
    </Link>
  </div>
);

DoctorView.jsx DoctorView.jsx

const DoctorItem = ({ doctor, match }) => (
  <div>
    <Link
      to={{ pathname:`/doctor/${doctor.profile.first_name}-${doctor.profile.last_name}` }}>
      {doctor.profile.first_name} {doctor.profile.last_name}
    </Link>
  </div>
);

I have access to the list of doctors via Redux, I could connect the component, bring in the list and compare id's but that feels like a lot of unnecessary steps.我可以通过 Redux 访问医生列表,我可以连接组件,引入列表并比较 id,但这感觉像是很多不必要的步骤。

But how do I get the selected doctor data to DoctorView?但是如何将选定的医生数据获取到 DoctorView?

Keep in mind that having paths like /items and /items/:id creates a scenario where you might be landing on the details page first.请记住,像/items/items/:id这样的路径会创建一个场景,您可能会首先登陆详细信息页面。

Do you:你:

a) fetch all the items anyways because you might go back to the list page? a) 无论如何都要获取所有项目,因为您可能会返回列表页面?

b) just fetch that the information for that one item? b) 只是获取那一项的信息?

Neither answer is "correct" but at the end of the day you have three possible pieces of information:这两个答案都不是“正确的”,但在一天结束时,您将获得三种可能的信息:

1) the item id 1) 物品编号

2) a single item 2)单品

3) a list of items (which may or may not contain all of the information you need for the details page) 3) 项目列表(可能包含也可能不包含详细信息页面所需的所有信息)

Wherever you want to display the full details of an item, it needs to have access to that item via props.无论您想在何处显示项目的完整详细信息,都需要通过 props 访问该项目。 Putting all of the item details in the url would be arduous, plus it would make it impossible to do situation A.将所有项目的详细信息放在 url 中会很费力,而且不可能做到情况 A。

Since you're using redux, it makes perfect sense grab the details of the item from the identifier in the url由于您使用的是 redux,因此从 url 中的标识符中获取项目的详细信息是非常有意义的

export default 
  connect((state, props) => ({
    doctor: state.doctorList.find(doctor => 
      doctor.id === props.match.params.id
    )
  }))(DoctorView)

Does ^ seems like too many extra steps? ^ 似乎有太多额外的步骤吗?

While the answer above solves the issue perfectly, I just want to add that using an inline function with component is not advised by react-router虽然上面的答案完美地解决了这个问题,但我只想补充一点, react-router不建议使用带有component的内联函数

Instead of doing:而不是做:

<Route path={`${match.url}/:name`}
  component={ (props) => <DoctorView doctor={this.props.doctors} {...props} />}
  />

You should instead use it like:你应该像这样使用它:

 <Route path={`${match.url}/:name`}
  render={ (props) => <DoctorView doctor={this.props.doctors} {...props} />}
  />

This will prevent the same component from being created on every mount and instead use the same component and update the state accordingly.这将防止在每次安装时创建相同的组件,而是使用相同的组件并相应地更新状态。

Hope this will help someone希望这会帮助某人

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM