【问题标题】:React Router <Link> and <Route> not passing state to ComponentReact Router <Link> 和 <Route> 没有将状态传递给组件
【发布时间】:2020-01-09 16:23:44
【问题描述】:

React Router:链接和路由未将状态传递给组件

我正在使用 React、Redux 和 React Router 构建一个在线购物应用程序。在主页上,显示所有项目。我希望用户能够单击图像并被带到包含该项目的项目详细信息的页面。

这就是我的尝试:

  • 在 App.js 中,我使用 BrowserRouter、Route 和 Switch 进行路由
  • 在 Home.js 中,我使用 react-router 的链接将主页上的图像链接到项目详细信息页面; Link 应该将 ID 作为状态传递给 Item 组件(参见下面的 Home.js 代码)
  • Item.js 应该呈现一个项目详细信息页面。项目的 ID 将传递给 Item 组件,该组件将呈现该项目的详细信息。

这看起来很简单,我在 SO 和网络上看到了很多关于这个的讨论。以下是我已经尝试过的一些:

Display item details after clicking Link in React Router

React router how to click thru to detail components

Passing values through React-Router v4 <Link />

Tyler McGinnis - Pass props to React Router's Link component

Medium - How to pass props to React routes components

我能够让 URL 更改为对应于项目的 ID,但我无法让项目组件以正确的信息呈现,有时我会收到错误,具体取决于我使用的方法。我在 Item.js 的一个 div 中硬编码了单词“Item Component”,当我单击主页上的图像时,它将呈现。否则,什么都不会呈现 或 我收到以下两个 TypeErrors:

App.js:

<Route path="/products" render={(props) => (<Item {...props} id={this.props.location.id} />) }/>

export default withRouter(App);

&lt;App /&gt; 被包裹在 index.js 中的&lt;BrowserRouter&gt; 中。

点击主页上的图片时出现以下错误:

TypeError:无法读取未定义的属性“props”

当上面的“render”代码被删除并替换为“component={ Item }”时,我从 Item.js 收到以下错误: TypeError:无法读取未定义的属性“位置”


这是我的其他代码sn-ps:

Item.js:

class Item extends React.Component {
    constructor() {
        super();

        this.state = {
            item: this.props.location.state
        }
    }

    render() {
        let item = this.state.item;
        return (
            <div className="item" key={item.id}>
                <div className="item-image">
                    <img src={item.img} alt={item.title} />
                </div>
                <div className="card-component">
                    <span className="item-title">{item.title}</span>
                    <p className="item-price"><b>${item.price}</b></p>
                    <p className="item-desc">{item.desc}</p>
                </div>
            </div>
        );
    }
}

Home.js(显示所有项目的地方),项目详细信息页面链接如下:

<Link to = 
    {{ pathname: `/products/${item.category}`,
    search: `?id=${item.id}`,
    state: {id: `${item.id}`} }}
    component={ Item }>
    <img src={item.img} alt={item.title} />
</Link>

更新

我已将&lt;Item/&gt; 组件包装在withRouter() 中。 在 Item.js 中,如果我将构造函数中的状态设置为 { item: this.props.location.state },则不会呈现应有的效果(屏幕上只有一个美元符号,因为价格部分包含一个硬编码的美元符号)。

我尝试在构造函数中将 Item.js 状态设置为null,然后在componentDidMount() 中使用{ item: this.props.location.state } 调用this.setState。当我这样做时,我收到以下错误:

TypeError:无法读取 null 的属性“img”

此外,如果我将 render={(props) =&gt; (&lt;Item {...props} id={this.props.location.id} /&gt;) } 留在 &lt;Route&gt; 中的 App.js 中,我会收到此错误:

TypeError:无法读取未定义的属性“props”

如果我将 &lt;Route&gt; 改回 component={ Item },并且 Item.js 构造函数状态设置为 { item: this.props.location.state },则只会呈现美元符号。

更新:包括 App.js 和 Routes.js 代码

App.js

import React from 'react';
import {
  BrowserRouter as Router,
  withRouter,
  Switch
} from 'react-router-dom';
import './App.css';
import Navbar from './components/Navbar';
import Footer from './components/footer/Footer';
import { Routes } from './constants/Routes';


class App extends React.Component {
  render() {
    return (
      <Router>
        <div className="App">
          <Navbar />
          <Switch>
            { Routes }
          </Switch>
          <Footer />
        </div>
      </Router>
    );
  }
}

export default withRouter(App);

Routes.js

import React from 'react';
import { Route } from 'react-router-dom';
import Home from '../components/Home';
import Item from '../components/shopping/Item';
import Cart from '../components/cart/Cart';
import OrderStatus from '../components/footer/OrderStatus';
import GiftCards from '../components/footer/GiftCards';
import ReturnsExchanges from '../components/footer/Returns-Exchanges';
import Contact from '../components/footer/Contact';

export const Routes = <div>
            <Route exact path="/" component={ Home } />
            <Route path="/products" component={ Item }/>
            <Route path="/cart" component={ Cart } />
            <Route path="/order-status" component={ OrderStatus } />
            <Route path="/gift-cards" component={ GiftCards } />
            <Route path="/returns-exchanges" component={ ReturnsExchanges } />
            <Route path="/contact" component={ Contact } />
            </div>

【问题讨论】:

  • 嗨,你用withRouter 包裹了你的App 组件吗?
  • 您好,感谢您的评论。我刚刚尝试过,但我现在遇到了一个新错误。我会更新我原来的帖子。
  • 新的错误似乎与BrowserRouter有关。在下面查看我的答案。希望能帮助到你。此外,查看您的App.js 代码将很有帮助。
  • 抱歉,我刚刚看到您对 App.js 代码的编辑。我将编辑我的问题并将其包含在底部。
  • 我发现这是一个写得很好的问题,我希望每个人在发布@Jenna时都能像你一样详细

标签: reactjs react-redux react-router


【解决方案1】:

在任何组件中访问history 对象属性的一种方法是,您需要用withRouter 包装该组件。 从react-router-dom 导入withRouter 并像这样包装你的App 组件:

export default withRouter(App);

更多关于withRouter。

另外,在index.js 中,确保您的&lt;App /&gt; 包含在&lt;BrowserRouter&gt; 中。

import { BrowserRouter } from 'react-router-dom';

ReactDOM.render(
   <BrowserRouter>
     <App />
   </BrowserRouter>
, document.getElementById('root'));

编辑:

TypeError:无法读取未定义的属性“props”

将您的constructor 替换为以下代码。在为 React 组件实现构造函数时,super(props) 应该在任何其他语句之前,否则 props 将在构造函数中为 undefined。

constructor(props){
    super(props);
    this.state = {
        item: this.props.location.state
    }
}

错误:TypeError:无法读取属性 'img' of null

原因: 状态的初始值不应该是null。在这种情况下,您可以传递空对象 {} 但不能传递 null。 您正在尝试访问Item.js 中的img、title、price 和desc,但只在state 中传递id 和&lt;Link&gt; 中的Home.js。

<Link to = 
    {{ pathname: `/products/${item.category}`,
       search: `?id=${item.id}`,
       state: {id: `${item.id}`} //pass img, title, desc, price etc as well
    }}
    component={ Item }>
    <img src={item.img} alt={item.title} />
</Link>

【讨论】:

  • 我刚刚更改了我的 index.js 以将 &lt;App /&gt; 组件包装在 &lt;BrowserRouter&gt; 中,以便处理该错误。但是,当我单击其中一个项目图像并被定向到项目详细信息页面时,我现在收到错误消息。我将编辑我原来的问题。
  • 尝试用 withRouter 包装你的“Item”组件。问题是,您必须包装任何需要访问 this.props.location 的组件。
  • 我已经这样做了,并将更新我的问题。再次感谢您的帮助。可能看起来不像,但我可能正在取得一些进展......?
  • 抱歉耽搁了。我已经编辑了我的答案,试图解决最近的错误。请让我知道它是否有效。
  • 非常感谢您的帮助以及您花在这方面的时间。我有一个严重的隧道视力问题,并且只专注于那个 ID 号码。我还了解了更多关于withRouter() 的功能,所以另外感谢您!
猜你喜欢
  • 1970-01-01
  • 2019-09-29
  • 2018-01-29
  • 2019-12-05
  • 1970-01-01
  • 2018-12-27
  • 1970-01-01
  • 2016-03-19
  • 2018-10-01
相关资源
最近更新 更多