I generate a link with a "navlink" in a component called "ProductCard" and I want to pass the props to a component called "Product"
ProductCard Component
import React, {Component} from "react";
import {NavLink} from "react-router-dom";
class ProductCard extends Component{
render() {
return (
<div className="col-xl-4 col-md-6 col-xs-12">
Name : {this.props.product.name}<br/>
Price : {this.props.product.price}<br/>
<NavLink
to={{
pathname:"/product/" `${this.props.producto.id}`,
aboutProps:{
product_id: `${this.props.product.id}`,
product_name: `${this.props.product.name}`,
product_sku: `${this.props.product.sku}`,
}
}}
exact
> Show product
</NavLink>
</div>
);
}
}
export default ProductCard;
Product.js Component
import React, {Component} from "react";
class Product extends Component{
constructor(props) {
super(props);
console.log(props.location.aboutProps);
this.state = {
products: []
}
}
render() {
return (
<div className="app container" style={{backgroundColor: "red", padding: "10px"}}>
Product<br/>
</div>
);
}
}
export default Product;
As I say, the problem I have is being able to pass the properties of the parent ProductCard component to the Child Product component
CodePudding user response:
EDIT: change to using state instead
state: {
product_id: this.props.product.id,
product_name: this.props.product.name,
product_sku: this.props.product.sku
}
Access the props like this: props.location.state.product_id
CodePudding user response:
TLDR: Change your approach. Example with pointers
Example here https://codesandbox.io/s/brave-visvesvaraya-81c0p?file=/src/App.js
In addition to @ilernet answer, I would like to give a few tips on your code:
With the solution above your links will end up like
/products/1/test/1223345
. This is not a good practice if you have lots of data
const linkData = await fetch(`/productdata`);
// linkData will equal array of 10 products
// { id: 1, sku: 1, name: "Product 1"}
linkData.forEach(data => {
return (
<NavLink
to={{
pathname:"/product/" `${data.id}`,
aboutProps:{
product_id: `${data.id}`,
product_name: `${data.name}`,
product_sku: `${data.sku}`,
}
}}
exact
>
Show product
</NavLink>
);
}
BUT
With React you should load as much data as needed by each component.
Recommendations
- Change your link approach
// This accepts anything like /product/123
<Route
exact
path="/product/:id"
render={({ match }) => {
// Render can be used to instead of state - to inject props directly into a component
return <ProductCard id={Number(match.params.id)} />;
}}
/>
- Fetch your data inside the Product/ProductCard Component
import React, { Component } from "react";
class ProductCard extends Component {
constructor(props) {
super(props);
// Replaces a fetch()/API request
this.state = {
products: [
{
id: 123,
name: "Test",
price: 1234
}
]
};
}
render() {
const { name, price } = this.currentProduct;
return (
<div className="col-xl-4 col-md-6 col-xs-12">
Name : {name}
<br />
Price : {price}
<br />
</div>
);
}
get currentProduct() {
const { id } = this.props;
if (!id) {
return {
name: "No Item",
price: 0
};
}
const { products } = this.state;
const currentProduct = products.find((product) => product.id === id);
return {
name: (currentProduct && currentProduct.name) || "No Item",
price: (currentProduct && currentProduct.price) || 0
};
}
}
export default ProductCard;