Хук useEffect не выполняетсяJavascript

Форум по Javascript
Ответить
Anonymous
 Хук useEffect не выполняется

Сообщение Anonymous »

Я создаю обувной веб-сайт, но есть проблема в следующем компоненте, обычно он работает нормально, но когда я пытаюсь скопировать URL-адрес в другой вкладке и попытаться открыть его напрямую, это выдает мне ошибку, потому что я предполагалось получать данные из родительского маршрута, и я попробовал следующий обходной путь, но он не работает, но почему

Код: Выделить всё

export default function Article() {
console.log("component is rendered");
const { user } = useAuth();
const navigate = useNavigate();
const {id} = useParams();
// article data coming from previous route
const location = useLocation()
const { article } = location.state || {};
// cart
const { addToCart , articleLoadingState , setArticleLoadingState } = useCart();
const [sales, setSales] = useState(0);

const [Article,setArticle] = useState(article);

console.log(article)
useEffect(() => {
const fetchArticleData = async () => {
console.log("fetch article data");
if (!article) {
try {
const docRef = doc(db, "Articles", id);
const docSnap = await getDoc(docRef);

if (docSnap.exists()) {
console.log(docSnap.data());
setArticle(docSnap.data());
}
} catch (err) {}
} else {
setArticle(article);
}
};

fetchArticleData(); // Call the async function
}, [article,id]);

Код: Выделить всё

console.log(article)
печатает неопределенное значение в консоли, но тогда почему console.log("fetch data data") не печатается в консоли, что означает, что перехватчик не выполняется, но почему и console.log («компонент визуализируется»); также работает, и я получаю ошибку:

Код: Выделить всё

Article.jsx:49 Uncaught TypeError: Cannot read properties of undefined (reading 'colors')
at Article (Article.jsx:49:76)
из-за этой строки в коде

Код: Выделить всё

    const [selectedColor, setSelectedColor] = useState(Object.keys(Article.colors)[0],);

это код компонента приложения

Код: Выделить всё

function App() {
return (














{/* Protected Routes */}







);
}

export default App;
полный код компонента

Код: Выделить всё

import React, { useState, useEffect } from "react";
import { MdAddShoppingCart } from "react-icons/md";
import { Button , Spinner } from "@nextui-org/react";
import { fireIcon } from "../../assets/images";
import { useNavigate , useLocation , useParams} from "react-router-dom";
import { useCart } from "../../context/CartContext";
import { useAuth } from "../../context/AuthManager";
import { doc, getDoc } from "firebase/firestore";

export default function Article() {
console.log("component is rendered");
const { user } = useAuth();
const navigate = useNavigate();
const {id} = useParams();
// article data coming from previous route
const location = useLocation()
const { article } = location.state || {};
// cart
const { addToCart , articleLoadingState , setArticleLoadingState } = useCart();
const [sales, setSales] = useState(0);

const [Article,setArticle] = useState(article);

console.log(article)
useEffect(() => {
const fetchArticleData = async () => {
console.log("fetch article data");
if (!article) {
try {
console.log("fetch article data");
const docRef = doc(db, "Articles", id);
const docSnap = await getDoc(docRef);

if (docSnap.exists()) {
console.log(docSnap.data());
setArticle(docSnap.data());
}
} catch (err) {}
} else {
setArticle(article);
}
};

fetchArticleData(); // Call the async function
}, [article,id]);

// article data
const [selectedColor, setSelectedColor] = useState(Object.keys(Article.colors)[0],);// currently selected color
const [selectedImage, setSelectedImage] = useState(0); // Track the active image index
const [imageCounter, setImageCounter] = useState(1); // Track the current image number (1-indexed)
const [isTransitioning, setIsTransitioning] = useState(true); // To control the sliding effect
const [selectedSize, setSelectedSize] = useState(Article.sizes[0]); // Default to the first size
const [amount, setAmount] = useState(1);

// destructing the article data
const { colors, images } = Article;
const articleData = {
articleNo: Article.id,
originalPrice: Article.price,
discount: Article.discount,
available: Article.available,
images,
category: Article.collection,
vendor: Article.vendor,
sizes: Article.sizes,
colors,
};

// fn for adding component to cart
const handleAddToCart = async () => {
setArticleLoadingState(true);

const cartItem = {
id: Article.id,
originalPrice: Article.price,
discount: Article.discount,
available: Article.available,
images: images[selectedColor],
category: Article.collection,
vendor: Article.vendor,
size: selectedSize,
color: selectedColor,
quantity: amount,
};

try {
await addToCart(cartItem); // Add item to the cart
} catch (error) {
} finally {
setArticleLoadingState(false);
}
};

const discountedPrice =
articleData.originalPrice * (1 - articleData.discount / 100);

const handleColorChange = (color) => {
setSelectedColor(color);
setSelectedImage(0); // Reset selected image when changing color
setImageCounter(1); // Reset counter when changing color
setIsTransitioning(false); // Temporarily stop the sliding effect
};

const handleImageSelect = (index) => {
setSelectedImage(index); // Update the active image
setImageCounter(index + 1); // Update the counter (1-indexed)
};

// Set up the automatic image change every 5 seconds
useEffect(() => {
const interval = setInterval(() =>  {
setSelectedImage((prevIndex) => {
let nextIndex = prevIndex + 1;

// If the next index exceeds the number of images, reset to 0
if (nextIndex >= articleData.images[selectedColor].length) {
nextIndex = 0;
setIsTransitioning(false); // Stop the sliding effect temporarily
setTimeout(() => {
setIsTransitioning(true); // Re-enable the sliding effect after a brief pause
}, 0); // Wait for a short period before re-enabling the transition
}

setImageCounter(nextIndex + 1); // Update counter (1-indexed)
return nextIndex;
});
}, 5000); // Change every 5 seconds

return () => clearInterval(interval); // Clean up the interval when the component unmounts
}, [selectedColor, articleData.images]);

useEffect(() => {
// Set initial sales value to a random number between 10 and 15
const initialSales = Math.floor(Math.random() * (15 - 10 + 1)) + 10;
setSales(initialSales);

// Set up interval to increment sales by 1, 2, or 3 every 2 minutes
const interval = setInterval(
() => {
const increment = Math.floor(Math.random() * 3) + 1; // Random value between 1 and 3
setSales((prevSales) => prevSales + increment);
},
5 * 60 * 1000,
); // 2 minutes in milliseconds

return () => clearInterval(interval); // Clean up the interval on component unmount
}, []);

return (




{/* Main Image with Sliding Effect */}

{articleData.images[selectedColor].map(
(image, index) => (
[img]{image}
className="w-full"
/>
),
)}



{articleData.images[selectedColor].map(
(image, index) => (
  handleImageSelect(index)} // Update the active image on click
>
[img]{image}
className="w-11/12"
/>

),
)}



FOOTPULSE

{articleData.articleNo}

{articleData.discount > 0 && (

-{articleData.discount}%

)}


[img]{fireIcon} alt=[/img]
{sales} sold in last 12 hours

Rs.{discountedPrice.toFixed(2)}

{articleData.discount > 0 && (

Rs.{articleData.originalPrice}

)}



 Available :{" "}
{articleData.available
? "In Stock"
: "Out of Stock"}

 Vendor :{" "}
{articleData.vendor}

 Type :{" "}
{articleData.category}

Sizes:
{articleData.sizes.map((size, index) => (
 setSelectedSize(size)} // Update the selected size
>
{size}

))}

Colors:
{Object.keys(articleData.colors).map((color, index) =>  (
 handleColorChange(color)}
>
))}



setAmount((prev) => Math.max(prev - 1, 1))
}
>
-

{amount}
 setAmount((prev) => prev + 1)}
>
+



{articleLoadingState ? (

) : (

Add to Cart


)}


 {
handleAddToCart()
if (user) {
addToCart();
navigate("/checkout")
} else {
navigate("/login")
}
}}
>
Buy Now







);
}

и URL-адрес выглядит так
http://localhost:5173/products/casual/AP34524
скажите мне, если вам нужно что-нибудь еще

Подробнее здесь: https://stackoverflow.com/questions/793 ... g-executed
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Javascript»