I use two components:
-"CartContainer.jsx" to count the cost of products that user has added to the cart.
UPDATED:
import React, { useEffect, useState } from "react";
import { useStateValue } from "../context/StateProvider";
import { actionType } from "../context/reducer";
//another imports
import { Link } from "react-router-dom";
import PaymentContainer from "./PaymentContainer";
const CartContainer = () => {
const [{ cartShow, cartItems, user }, dispatch] = useStateValue();
const [flag, setFlag] = useState(1);
const [tot, setTot] = useState(0);
//another methods
useEffect(() => {
let totalPrice = cartItems.reduce(function (accumulator, item) {
return accumulator + item.qty * item.price;
}, 0);
setTot(totalPrice);
console.log(tot);
}, [tot, flag]);
//another methods
return (
<motion.div initial... animate... exit... class...">
//something code
{/* bottom section */}
//something code
{/* cart total section code */}
<div class...>
<div class...>
<p class...>Sub Total</p>
<p class...>$ {tot}</p>
</div>
<div class...>
<p class...>Delivery</p>
<p class...>$ 2.5</p>
</div>
//another code
<div class...>
<p class...>Total</p>
<p class...>${tot + 2.5}</p>
</div>
{user ? (
<Link to={'/payment'}> *//it's link to PaymentContainer*
<motion.button whileTap={{ scale: 0.8 }} type="button" class...>Check Out</motion.button>
</Link>
) : (
//another code
)}
</div>
<div>
<PaymentContainer totalAmount={tot} />
</div>
</div>
) : (
//another code
)}
</motion.div>
);
};
export default CartContainer;
-"PaymentContainer.jsx" this component works with Stripe.js and has a "amount"-variable.
UPDATED:
import React from "react";
const PaymentContainer = ({totalAmount}) => {
const containerAmount = totalAmount;
console.log(totalAmount);
return (
<div>
<h2>Total: {containerAmount}</h2>
</div>
);
};
export default PaymentContainer;
I want the total cost of items from "CartContainer.jsx" to be assigned to the "amount"-variable in "PaymentContainer.jsx"
Thank you all 🙂
I found a similar question in this forum and tried to apply the solution, but I couldn’t.
I tried to adapt this code in file "PaymentContainer.jsx"
const handleInputChange = (e) => {
const valueFilterActive = document.getElementById("activeFilter").value;
const valueFilterName = document.getElementById("bussFilter").value;
// this will set `inputValues` variable to be an object with `valueFilterActive` and `valueFilterName` properties
setInputValues({valueFilterActive, valueFilterName})
alert(valueFilterName+valueFilterActive);
};
UPDATED: App.js
import React, { useEffect } from "react";
import { Route, Routes } from "react-router-dom";
import { AnimatePresence } from "framer-motion";
import { CreateContainer, Header, MainContainer, PaymentContainer } from "./components";
import { useStateValue } from "./context/StateProvider";
import { getAllFoodItems } from "./utils/firebaseFunctions";
import { actionType } from "./context/reducer";
const App = () => {
const [{foodItems}, dispatch] = useStateValue();
const fetchData = async () => {
await getAllFoodItems().then(data => {
dispatch({
type : actionType.SET_FOOD_ITEMS,
foodItems : data,
});
});
};
useEffect(() => {
fetchData();
}, []);
return (
<AnimatePresence mode="wait">
<div class...>
<Header />
<main class...>
<Routes>
<Route path="/*" element={<MainContainer />} />
<Route path="/createItem" element={<CreateContainer />} />
//here PaymentContainer
<Route path="/payment" element={<PaymentContainer />} /> here PaymentContainer
//here PaymentContainer
</Routes>
</main>
</div>
</AnimatePresence>
);
}
export default App
2
Answers
in React, you can pass data to other components via props or global state, so one way would be to render the
PaymentContainer.jsx
inside theCartContainer.jsx
and pass data to it.For example:
Your payment Container would also need to receive the props to view
Reference: https://reactjs.org/docs/components-and-props.html
Issue
You are rendering the
PaymentContainer
component in at least two places, once inCartContainer
where atotalAmount
prop is passed:And once in the routes where no props are passed:
It is the second that when navigated to by the
Link
inCartContainer
that the total is undefined.A Solution
It’s not clear why you are rendering
PaymentContainer
in two places differently, so I’ll ignore this part. If you want to renderPaymentContainer
on a route and pass data to it you will pass it in route state via the link.The
tot
state is actually also unnecessary since it’s derived "state" from the actualcartItems
state. It’s generally considered a React anti-pattern to store derived state in React state. You should compute and use it locally per render cycle.Note that in almost 100% of the use cases where you find yourself coding a
useState/useEffect
hook combo what you really should use is theuseMemo
hook to compute and memoize a stable value reference.Examples:
Code Example: