Ricky Ricky - 10 months ago 84
React JSX Question

Child component not updating in React

Help! My child component is not updating in my react app!

I want to bring cartNumber to the page component which then is passed onto header component but the number doesn't even show up!

Parent component

class Shop extends Component {
constructor(props) {
super(props);
this.state = {
merchants: [],
error: null,
loading: true,
order: []
};
}

componentWillMount() {
Meteor.call("merchants.getMerchants", (error, response) => {
if (error) {
this.setState(() => ({ error: error }));
} else {
this.setState(() => ({ merchants: response }));
}
});
}

componentDidMount() {
setTimeout(() => this.setState({ loading: false }), 800); // simulates loading of data
}

goBack = () => this.props.history.push("/");
goCart = () => {
try {
Orders.insert(this.state.order), this.props.history.push("/cart");
} catch (error) {
throw new Meteor.Error("there was an error", error);
}
};

onAddToCart(cartItem) {
let { order } = this.state;
order.push(cartItem);
console.log(order.length);
}

render() {
const { loading } = this.state;
const { merchants, error } = this.state;
const { data } = this.state;
const { order } = this.state;

const getProductsFromMerchant = ({ products, brands }) =>
products.map(({ belongsToBrand, ...product }) => ({
...product,
brand: brands[belongsToBrand]
}));

const products = merchants.reduce(
(acc, merchant) => [...acc, ...getProductsFromMerchant(merchant)],
[]
);

if (loading) {
return (
<Page
pageTitle="Shop"
history
goBack={this.goBack}
goCart={this.goCart}
>
<div className="loading-page">
<i
className="fa fa-spinner fa-spin fa-3x fa-fw"
aria-hidden="true"
/>
<br /> <br />
<span>Loading...</span>
</div>
</Page>
);
}

return (
<Page
pageTitle="Shop"
history
goBack={this.goBack}
goCart={this.goCart}
cartNumber={order.length}
>
<div className="shop-page">
{products.map(({ id, ...product }) =>
<Product
{...product}
key={id}
history
onAddToCart={this.onAddToCart.bind(this)}
/>
)}
</div>
</Page>
);
}
}

export default Shop;


Here is the page component which contains the header component

export const Page = ({
children,
pageTitle,
history,
goBack,
goCart,
cartNumber
}) =>
<div className="page">
<Header goBack={goBack} goCart={goCart} history cartNumber>
{pageTitle}
</Header>
<main>
<MuiThemeProvider>
{children}
</MuiThemeProvider>
</main>
<Footer />
</div>;

export default Page;


And Finally this is the header where I want to bring the cartNumber into.

const Header = ({ children, goBack, goCart, cartNumber, pageTitle }) =>
<header>
<button onClick={goBack} className="back-button">
{/* Image added here to show image inclusion, prefer inline-SVG. */}
<img alt="Back" src={`/icon/header/back-white.svg`} />
</button>
<h1>
{children}
</h1>
<div className="right-content">
( {cartNumber} )
<i
className="fa fa-shopping-cart fa-2x"
aria-hidden="true"
onClick={goCart}
/>
</div>
</header>;
export default withRouter(Header);

Answer Source

You're passing cartNumber as a boolean:

<Header goBack={goBack} goCart={goCart} history cartNumber>

Pass it as a value:

<Header goBack={goBack} goCart={goCart} history={history} cartNumber={cartNumber}>
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download