I am trying to use React Context in my project. I implemented a provider component and I am consuming the data in two child components. But when I update the state of the Provider component from one of the children, the other child is not re-rendered with the data from the provider component.
I am using these characteristics of React Context to avoid passing the props from component to component. As I have implemented it in the past
// Parent Provider
const {Provider, Consumer} = React.createContext()
class ShoppingCartProvider extends React.Component{
constructor(props){
super(props)
this.state = {
order: {},
Total: 0,
}
}
addOrder = (key) => {
const order = this.state.order
let totalOrder = this.state.Total
order[key] = order[key] + 1 || 1
this.setState({order})
totalOrder = totalOrder + 1
this.setState({Total: totalOrder})
}
render(){
return(
<Provider value={{
order: this.state.order,
addOrder: this.addOrder,
totalOrder: this.state.Total
}}>
<div>{this.props.children}</div>
</Provider>
)
}
}
export {ShoppingCartProvider, Consumer as ShoppingCartConsumer}
// child that changes the parent state
import React, {useContext } from 'react';
const ItemProducto = props =>{
const {product} = props
const {addOrder} = useContext(ShoppingCartConsumer)
return <Grid item>
<div css={botonAdd}
onClick={()=>{
addOrder(product._id)
}}>Add</div>
</Grid>
}
export default ItemProducto
//This is not re-rendered when the state in parent component changes
import React, {useContext, useEffect, useState} from 'react';
const Header = props =>{
const {totalOrder} = useContext(ShoppingCartConsumer)
const [count, setcount] = useState(totalOrder)
useEffect(()=>{
setcount(totalOrder)
})
return (
<div>
<Grid item css={numeroDinero}>{count}</Grid>
</div>
)
}
export default Header
I expect a re-render in Header child when ItemProducto child change a Total state property.
Everything in your code checks out except one. The useContext()
expects the actual context as an argument not the consumer. In your case you passed in the consumer by doing this: export {..., Consumer as ShoppingCartConsumer }
.
All you need to do to fix the issue is this: In ShoppingCartContext
change:
const { Provider, Consumer } = React.createContext()
to
const ShoppingCartContext = React.createContext();
.
And in your render
:
render() {
return (
<ShoppingCartContext.Provider
value={{
order: this.state.order,
addOrder: this.addOrder,
totalOrder: this.state.Total
}}
>
<div>{this.props.children}</div>
</ShoppingCartContext.Provider>
);
}
Then change your export to: export { ShoppingCartProvider, ShoppingCartContext };
Modify the imports in the Header
and ItemProducto
accordingly, and do not forget to pass ShoppingCartContext
to their respective useContext()
s.
For more info on useContext
see here
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.