Reputation: 1952
I'm having this React functional component. We know that since v16.8, functional component has kind of "state". It uses useEffect to "setState" to state variable products. Then I pass product as prop for the child component *ProductGrid". I have the ProductOfCategory as parent component, it will fetch data from an URL and set the result to state variable "products". I want the child component ProductGrid to be able to read that data (change), so I made it looks like this.
Parent:
export default function ProductOfCategory() {
let { categoryId } = useParams();
const [products, setProducts] = useState([]);
useEffect(() => {
fetch('/products/cat/' + categoryId)
.then(response => response.json())
.then(data => {
setProducts(data);
console.log("Fetch me: ", data);
});
}, [categoryId]);
return (
<div>
<h3>ID: {categoryId}</h3>
<ProductGrid products={products} />
</div>
);
}
Child:
class ProductGrid extends Component {
constructor(props) {
super(props);
this.state = { products: this.props.products};
console.log("ProductGrid.props.products: ", this.props);
}
componentDidUpdate(prevProps, prevState, snapshot) {
console.log("Grid did update, products: ", this.state.products);
}
}
Result: When the data in parent changes, I can see (in the console) that the child component (ProductGrid) is re-rendered also, but its prop variable "products" is NOT. It's always an empty array. What is the reason of this? Does it mean that functional component's state is different from legacy state? Is there someway to overcome this?
Many thanks.
Upvotes: 0
Views: 2237
Reputation: 1927
You problem is on the line
console.log("Grid did update, products: ", this.state.products);
Here you are logging the state of the child component. When you construct the child component you copy the prop.products
to state.products
. Then when prop.product
changes you don't update the state to reflect that change, you continue to print the initial value of products
that was passed to the component.
The solution here would be to use this.props.products
instead of this.state.products
.
Upvotes: 1