使用组件页面上的URL来识别并通过React Router从父级传递状态数据?

Eva*_*nss 5 react-router-v4

我正在使用React Router.在我的州,我有一些可通过身份识别识别的电视节目.在节目页面上,我需要加载特定节目的数据,将节目ID与URL的末尾相匹配.

我的州看起来像这样,但有更多的节目:

shows: [
  {
    id: 1318913
    name: "Countdown"
    time: "14:10"
  },
  {
    id: 1318914
    name: "The News"
    time: "15:00"
  }
]
Run Code Online (Sandbox Code Playgroud)

在App.js中:

<BrowserRouter>
  <Switch>
    <Route
      exact
      path="/"
      render={() => {
        return <Table shows={this.state.shows} />;
      }}
    />
    <Route
      path="/show/:showID"
      render={() => {
        return <Show />;
      }}
    />
    <Route component={FourOhFour} />
  </Switch>
</BrowserRouter>;
Run Code Online (Sandbox Code Playgroud)

React Router在显示页面上显示URL的showID部分.所以我可以将我的整个show状态传递给Show组件,然后从url中找到正确的show.但是我想这个效率低下?

我想知道我是否应该通过App.js中的ID查看节目,并且只将正确的节目传递给Show组件.这是更好的做法/更有效吗?

这是我的表组件:

class Table extends Component {
  render(props) {
    return (
      <table className="table table-striped table-bordered table-hover">
        <tbody>
        {
          this.props.shows.map((item)=>{
            return <TableRow
              name={item.name}
              time={item.time}
              key={item.eppisodeId}
              eppisodeId={item.eppisodeId}
              img={item.img}
            />
          })
        }
        </tbody>
      </table>
    )
  }
}
Run Code Online (Sandbox Code Playgroud)

这是我的TableRow组件:

class TableRow extends Component {
  render(props) {
    const image = this.props.img !== null ?
      <img src={this.props.img} alt={this.props.name} />
      : null;
    const showUrl = '/show/' + this.props.eppisodeId;
    return (
      <tr className="tableRow">
        <td className="tableRow--imgTd">{image}</td>
        <td><Link to={showUrl}>{this.props.name}</Link></td>
        <td className="tableRow--timeTd">{this.props.time}</td>
      </tr>
    )
  }
}
Run Code Online (Sandbox Code Playgroud)

Eva*_*nss 0

组件参数可以接受一个函数。如果你传递 props,那么props.match.params.id你可以从 url 中找到 ID。当我们在一个函数中时,我们可以从状态中找到显示并将其传递给显示组件。

<BrowserRouter>
  <Switch>
    <Route
      exact
      path="/"
      render={() => {
        return <Table shows={this.state.shows} />;
      }}
    />

    <Route path="/show/:id" component={(props)=>{
      const foundShow = this.state.shows.find((show)=>{
      const urlId = props.match.params.id;
         return show.eppisodeId === parseInt(urlId);
       });
       // {...props} is optional, it will pass the other properties from React Router
       return <Show show={foundShow} {...props} />
     }} />

    <Route component={FourOhFour} />
  </Switch>
</BrowserRouter>;
Run Code Online (Sandbox Code Playgroud)

然而,有一些奇怪的行为。如果我console.log(this.props);在“显示”组件中,那么我可以看到它被渲染两次。第一次this.props.show是空的,第二次它有我传递的数据。这真的很痛苦,因为我必须在渲染之前检查每个变量是否存在,这让我觉得我一定做错了什么......

更新:以下解决了上述问题,但我不知道这是否是一个好的做法:

class Show extends Component {
  render(props) {
    if (this.props.foundShow) {
      const {name, network, time} = this.props.foundShow;
      return (
        <div>
          <h2>
            {name} on {network} at {time}
          </h2>
        </div>
      )
    } else {
      return (
        <h2>Loading....</h2>
      )
    }
  }
}
Run Code Online (Sandbox Code Playgroud)