React Router <Link>和<Route>没有将状态传递给组件

时间:2019-09-06 20:04:15

标签: reactjs react-redux react-router

反应路由器:链接和路由未将状态传递给组件

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

这就是我要这样做的方式:

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

这似乎很简单,我已经在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内对“项目组件”一词进行了硬编码,当我单击主页上的图像时,它将呈现出来。否则,什么都不会呈现我收到以下两个TypeError:

App.js:

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

export default withRouter(App);

<App />包装在index.js的<BrowserRouter>中。

从主页上单击图像时收到以下错误:

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

从“ component = {Item}”中删除以上“渲染”代码后,我从Item.js收到此错误: TypeError:无法读取未定义的属性“位置”


这是我的其他代码段:

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>

更新

我已经将<Item/>组件包装在withRouter()中。 在Item.js中,如果我在构造函数中将状态设置为{ item: this.props.location.state },则不会呈现任何应有的状态(屏幕上仅显示美元符号,因为price部分包含硬编码的美元符号)。

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

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

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

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

如果我将<Route>改回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>

1 个答案:

答案 0 :(得分:2)

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

App

有关withRouter的更多信息。

还要在export default withRouter(App); 中,将index.js包裹在<App />内。

<BrowserRouter>

编辑:

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

用以下代码替换import { BrowserRouter } from 'react-router-dom'; ReactDOM.render( <BrowserRouter> <App /> </BrowserRouter> , document.getElementById('root')); 。在为React Component实现构造器时,constructor应该在其他任何语句之前,否则props将在构造器中成为super(props)

undefined

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

原因: 状态的初始值不应为constructor(props){ super(props); this.state = { item: this.props.location.state } } 。在这种情况下,您可以传递空对象null,但不能传递null。 您正在尝试访问{}中的imgtitlepricedesc,但仅通过Item.js中的id state中的<Link>

Home.js