使用组件页面上的 URL 通过 React Router 识别和传递来自父级的状态数据? [英] Use URL on a component page to identify and pass data in state from parent with React Router?

查看:37
本文介绍了使用组件页面上的 URL 通过 React Router 识别和传递来自父级的状态数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Im using React Router. In my state I have a number of TV shows identifiable by an ID. On the shows page I need to load the data for the specific show, matching the show ID to the end of the URL.

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

My state looks something like this but with more shows:

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

在 App.js 中:

In 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 中找到正确的节目.但是我认为这是低效的?

React Router makes the :showID part of the URL available on the shows page . So I could pass my entire show state to the Show component and then find the correct show from the url. However I imagine this is inefficient?

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

I was wondering if I should look up the show via the ID in App.js and only pass the correct show to the Show component. Is this better practice / more efficient?

这是我的表格组件:

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 组件:

Here is my TableRow component:

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 发送数据,您可以向它传递一个对象,而不是 React-router docs,这样就可以用TableRow中的state object传递show信息> 组件如

As I see in your question, you are using Link to navigate. Considering you want to also send the data with the Link, you can pass an object to it instead of the string path as mentioned in the React-router docs, So you can pass the show information with the state object in TableRow component like

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

现在您可以在 Show 组件中检索此信息为

Now you can retrieve this information in Show component as

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

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

The other thing that you need to take care of is, that you need to pass the props to the render function

 <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,它将不起作用,如果您想让它更健壮,则需要将数据传递给 show 组件然后在生命周期函数中进行优化

Now the above solution will work only if you navigate from within the App, but if you change the URL it won't work, if you want to make it more robust, you would need to pass the data to the show component and then optimise in the lifecycle functions

你会的.做喜欢

<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 组件中

And then in the Show component

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 
        }

    }
}

然而,这是像 reduxreselect 很有用.使用 Redux,您的数据 shows 将在一个公共存储中,您可以在任何组件中访问它,并且 reselect 为您提供了一个选项来创建一个选择器,该选择器被记忆以获得适当的show 数据来自shows,这样就不再重复相同的计算了.请探索这些并检查您是否发现它们适合您的项目.

However this is where libraries like redux and reselect are useful. with Redux your data shows will be in one common store and you can access it in any component and reselect gives you an option to create a selector that is memoized to get the appropriate show data from shows, so that the same calculation is not repeated again. Please explore about these and check if you find them a good fit for your project.

这篇关于使用组件页面上的 URL 通过 React Router 识别和传递来自父级的状态数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆