Here I am making a shopping app and I have a working cart in it and below is my code for my cart component and here in cart I want to render order button conditionally for that I have isFound state and first I am getting data from my redux store and then I am checking below in useEffect hook if my list is not empty(list is const where I am storing my redux fetched data) then I will set my state=true and initially it is false but the problem is that useEffect is chanigng state to true if there is nothing inside of my list const means even if cart is empty and even though I am setting useEfect dependency proprly as well but it is showing order button all the time so someone can please help thanks:
import { useEffect, useState } from "react";
import { useSelector } from "react-redux";
import { useNavigate } from "react-router-dom";
import classes from "./Cart.module.css";
const Cart = () => {
const navigate = useNavigate();
const [isFound, setIsFound] = useState(false);
const orders = useSelector((state) => state.data.DUMMY_DATA);
const list = orders.map(
(data, key) =>
data.product_count > 0 && (
<div className={classes.wrapper}>
<div className={classes.item}>
Item:   {data.product_name}{" "}
</div>
<div className={classes.amount}>
Amount:   {data.product_count}{" "}
</div>
<div className={classes.price}>
Price:   {data.product_price}
</div>
</div>
)
);
useEffect(() => {
if (list !== "") {
setIsFound(true);
}
}, [list]);
return (
<div className={classes.modal}>
<div className={classes.root}>
<span
className={classes.close}
onClick={() => navigate("/", { replace: true })}
>
×
</span>
{list}
{isFound && (
<div className={classes.order_button_wrapper}>
<button className={classes.order_button}>Order</button>
</div>
)}
</div>
</div>
);
};
export default Cart;
CodePudding user response:
.map alway return an array. So list !== ""
will alway be true.
CodePudding user response:
Here is useEffect, you have an array not a string as list value:
useEffect(() => {
if (list.length > 0) {
setIsFound(true);
}
}, [list]);
CodePudding user response:
You have placed a watcher on the list
variable, that's why useEffect
is not calling, you need to place a watcher on the state
because the state
is being rendered and when any changes to the state
useEffect
will be called, variable is not rendered That's is why useEffect
is not being called and changes to your component are not being replicated. You have to create a state
and put the list
value in the state and you have to call the function in the useEffect
because you only have one called otherwise your function will be calling, as you code below can see.
import { useEffect, useState } from "react";
import { useSelector } from "react-redux";
import { useNavigate } from "react-router-dom";
import classes from "./Cart.module.css";
const Cart = () => {
const navigate = useNavigate();
const [isFound, setIsFound] = useState(false);
const orders = useSelector((state) => state.data.DUMMY_DATA);
const [ordersList, setOrdersList] = useState("");
useEffect(() => {
const list = orders.map(
(data, key) =>
data.product_count > 0 && (
<div className={classes.wrapper}>
<div className={classes.item}>
Item:   {data.product_name}{" "}
</div>
<div className={classes.amount}>
Amount:   {data.product_count}{" "}
</div>
<div className={classes.price}>
Price:   {data.product_price}
</div>
</div>
)
);
setOrdersList(list);
}, [])
useEffect(() => {
if (ordersList !== "") {
setIsFound(true);
}
}, [ordersList]);
return (
<div className={classes.modal}>
<div className={classes.root}>
<span
className={classes.close}
onClick={() => navigate("/", { replace: true })}
>
×
</span>
{ordersList}
{isFound && (
<div className={classes.order_button_wrapper}>
<button className={classes.order_button}>Order</button>
</div>
)}
</div>
</div>
);
};
export default Cart;