用匹配路径反应路由器dom 5问题

时间:2020-09-25 23:13:28

标签: reactjs react-redux react-router-dom

单击指向路径的链接时,未激活使用该路径配置的路由。而是通配符的重定向被激活。我有一个ProductsList页面,其中显示产品列表,每个产品都有指向ProductDetails页面的链接。路由器位于App.js中。

App.js

class App extends React.Component {
    constructor(props) {
        console.log(localStorage.getItem("user"));
        super();

        history.listen((location, action) => {
            // clear alert on location change
            this.props.clearAlerts();
        });
    }

   

    render() {
        const { alert } = this.props;
        return (
            <div className="jumbotron" style={{backgroundColor:"white"}}>
                <div className="container">
                    <div className="col-sm-8 col-sm-offset-2">
                        {alert.message &&
                            <div className={`alert ${alert.type}`}>{alert.message}</div>
                        }
                        <Router history={history}>
                           <Switch>
                                <PrivateRoute exact  path="/" component={ProductsList} />
                                <Route  path="/login" component={LoginPage}/>
                                <Route  path="/register" component={RegisterPage} />
                                <PrivateRoute path="/product:id" component={ProductDetails}/>
                                <Redirect from="*" to="/"/>
                            </Switch>
                        </Router>
                    </div>
                </div>
            </div>
        );
    }
}

function mapState(state) {
    const { alert } = state;
    return { alert };
}

const actionCreators = {
    clearAlerts: alertActions.clear
};

const connectedApp = connect(mapState, actionCreators)(App);
export { connectedApp as App };

ProductsList.js

class ProductsList extends React.Component{
constructor(props){
    super(props);
    this.state={
        products:[]
    }
    setTimeout(()=>{
        productsService.getProducts().then((value)=>{
            this.setState({
                products: value
            })
        });
    });
   
}



render(){
    const products= this.state.products;

    return (
        <div id="products_list">
           { !products.length==0 && products.map((value)=>{
               return (<Product key={value.id} id={value.id} 
               img={value.name.replaceAll(" ","_")+".jpg"} 
               name={ value.name}
               cost={value.price} artist={value.artist}/>
               )
            })}
        </div>

    );
}
}

const routedComponent = withRouter(ProductsList);
export {routedComponent as ProductsList}

Product.js

class Product extends React.Component{
    constructor(props){
        super(props);
        
    }

    render(){
        const showDetails=('details' in this.props);
        const productDetails= this.props;
        return (
            <div>
                <div className={showDetails?"product-container-details":
                "product-container"}>
                <img className={showDetails?"product-image-details":
                "product-image"} src={"productImages/"+this.props.img}/> <br/>
                <div className={showDetails?"product-text-details":"product-text"}>
                    <Link to={{pathname:"/product:"/+productDetails.id,
                     state:{product:productDetails}}}> <h3> {this.props.name}</h3> </Link>
                    <p>{this.props.artist}</p>
                    <p>{this.props.cost}</p>
                </div>
                </div>
                <div className={showDetails?"product-border":"product-border-details"}> 
                </div>
            </div>
        );
    }
}

const  routerProduct = withRouter(Product);
export { routerProduct as Product}

ProductDetails.js

class ProductDetails extends React.Component{

    constructor(props){
        super(props);
    }

    render(){
        console.log("Here");
        console.log(this.props.location);
        const {product} =this.props.location.state;
        return(
            <Product id={product.id} 
            img={product.name.replaceAll(" ","_")+".jpg"} 
            name={ product.name}
            cost={product.price} artist={product.artist}/>
        )
    }
}

const routedPage = withRouter(ProductDetails);

export {routedPage as ProductDetails};

1 个答案:

答案 0 :(得分:0)

这很难说,但是我认为需要正确定义匹配路径,path="/product/:id"才能使id match参数起作用。 to={{ pathname: "/product:" / +productDetails.id似乎正在生成路由器无法匹配的格式错误的路径。

<PrivateRoute path="/product/:id" component={ProductDetails}/>

然后该链接应正确创建要匹配的有效链接,pathname:"/product/" + productDetails.id/product/${productDetails.id}

<Link
  to={{
    pathname: `/product/${productDetails.id}`,
    state: { product: productDetails },
  }}
>
  <h3>{this.props.name}</h3>
</Link>

如果您不使用匹配参数,那么我想这就是您想要的

<PrivateRoute path="/product:" component={ProductDetails}/>

<Link
  to={{
    pathname: pathname:"/product:" + productDetails.id,
    state: { product: productDetails },
  }}
>
  <h3>{this.props.name}</h3>
</Link>

通过这种方式,至少路径前缀“ / product:”匹配。