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

2024-02-23

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

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

shows: [
  {
    id: 1318913
    name: "Countdown"
    time: "14:10"
  },
  {
    id: 1318914
    name: "The News"
    time: "15:00"
  }
]

在 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>;

React Router 使 URL 的 :showID 部分在显示页面上可用。因此我可以将整个演出状态传递给 Show 组件,然后从 url 中找到正确的演出。但我认为这效率低下?

我想知道是否应该通过 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>
    )
  }
}

这是我的 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>
    )
  }
}

正如我在你的问题中看到的,你正在使用Link导航。考虑到您还想通过 Link 发送数据,您可以向其传递一个对象而不是string path如中提到的React-router 文档 https://reacttraining.com/react-router/web/api/Link,所以你可以通过state object in TableRow类似组件

const {name, time, episodeId, img} = this.props;
<Link to={{pathname:showUrl, state: {show: {name, time, episodeId, img }}}}>{this.props.name}</Link>

现在您可以在以下位置检索此信息Show组件为

this.props.location.state && this.props.location.state.name

您需要注意的另一件事是,您需要将道具传递给渲染函数

 <Switch>
       <Route
      exact
      path="/"
      render={(props) => {
        return <Table shows={this.state.shows} {...props}/>;
      }}
    />
    <Route
      path="/show/:showID"
      render={(props) => {
        return <Show {...props}/>;
      }}
    />
    <Route component={FourOhFour} />
  </Switch>

现在,上述解决方案仅在您从应用程序内部导航时才有效,但如果您更改 URL,它将不起作用,如果您想使其更加健壮,则需要将数据传递给显示组件,然后进行优化在生命周期函数中

你会 。这样做就像

<Switch>
       <Route
      exact
      path="/"
      render={(props) => {
        return <Table shows={this.state.shows} {...props}/>;
      }}
    />
    <Route
      path="/show/:showID"
      render={(props) => {
        return <Show shows={this.state.shows} {...props}/>;
      }}
    />
    <Route component={FourOhFour} />
</Switch>

然后在 Show 组件中

class Show extends React.Component {
    componentDidMount() {
        const {shows, match} = this.props;
        const {params} = match;
        // get the data from shows which matches params.id here using `find` or `filter` or whatever you feel appropriate

    }
    componentWillReceiveProps(nextProps) {
        const {match} = this.props;
        const {shows: nextShows, match: nextMatch} = nextProps;
        const {params} = match;
        const {params: nextParams} = nextMatch;
        if( nextParams.showId !== params.showId) {
            // get the data from nextProps.showId and nextShows here 
        }

    }
}

然而,这就是图书馆喜欢的地方redux http://redux.js.org/ and reselect https://github.com/reactjs/reselect很有用。 Redux 你的数据shows将位于一个公共商店中,您可以在任何组件中访问它,并且reselect为您提供了创建选择器的选项,该选择器被记忆以获得适当的show数据来自shows,这样就不会再次重复相同的计算。请探索这些并检查您是否发现它们适合您的项目。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐