Функция Next.js, выполняемая дважды

Моя функция addToCart запускается дважды при нажатии.

//Функция

const addToCart = useCallback(() => {
    if (produto && cartItems) {
      setCartItems((prev: LocalStorageItem[]) => {
        if (!Array.isArray(prev)) {
          return [
            {
              productId: produto.id,
              color: variavelAtual.color,
              quantity: quantidade,
            },
          ];
        }

        const itemExists = cartItems?.find(
          (item) => item.productId === produto.id
        );
        if (!itemExists || itemExists === undefined) {
          return [
            ...prev,
            {
              productId: produto.id,
              color: variavelAtual.color,
              quantity: quantidade,
            },
          ];
        } else {
          console.info(quantidade);
          console.info(itemExists.quantity);
          changeCartItemQuantity(
            produto.id,
            variavelAtual.color,
            itemExists.quantity + quantidade
          );
          return cartItems;
        }
      });
      toast.success("Produto Adicionado Com Sucesso");
      router.push("/cart");
      setIsAdded(true);
    }
  }, [
    cartItems,
    changeCartItemQuantity,
    produto,
    quantidade,
    router,
    setCartItems,
    variavelAtual.color,
  ]);

//Изменить функцию количества

function changeCartItemQuantity(
    productId: string,
    color: string,
    quantity: number
  ) {
    if (cartItems) {
      const newCartItem = cartItems.find(
        (item) => item.productId === productId && item.color === color
      );
      const newCartItemIndex = cartItems.findIndex(
        (item) => item.productId === productId && item.color === color
      );

      if (newCartItem) {
        newCartItem.quantity = quantity;

        const newCartItems = cartItems.map((item, index) =>
          index === newCartItemIndex ? newCartItem : item
        );

        setCartItems(newCartItems);
      }
    }
  }

//Только компонент, который его вызывает

"use client";
import CheckCircleRoundedIcon from "@mui/icons-material/CheckCircleRounded";
import DangerousRoundedIcon from "@mui/icons-material/DangerousRounded";

interface ProductButton {
  isAdded: boolean;
  selling: boolean;
  stock: number;
  cartQuantity: number;
  addToCart: () => void;
}

export default function ProductButton({
  isAdded,
  selling,
  stock,
  cartQuantity,
  addToCart,
}: ProductButton) {
  if (cartQuantity === stock || cartQuantity > stock) {
    if (stock === 0) {
      return <div></div>;
    } else {
      return (
        <>
          <div className = "flex items-center">
            <DangerousRoundedIcon
              className = "text-error mr-4"
              fontSize = "large"
            />
            <p className = "text-lg"> Limite de Estoque Atingido no Carrinho</p>
          </div>
        </>
      );
    }
  } else if (stock > 0 && selling) {
    return (
      <>
        {!isAdded ? (
          <button
            onClick = {addToCart}
            className = "bg-base-content text-base-100 rounded-md h-[3rem] w-full hover:bg-primary duration-300"
          >
            Adicionar ao Carrinho
          </button>
        ) : (
          <div className = "flex items-center">
            <CheckCircleRoundedIcon
              className = "text-success mr-4"
              fontSize = "large"
            />
            <p className = "text-lg"> Produto Adicionado ao Carrinho</p>
          </div>
        )}
      </>
    );
  } else if (!selling) {
    return (
      <>
        <div className = "flex items-center">
          <DangerousRoundedIcon className = "text-error mr-4" fontSize = "large" />{" "}
          <p className = "text-lg"> Produto Não está À Venda</p>
        </div>
      </>
    );
  } else {
    return (
      <>
        <div className = "flex items-center">
          <DangerousRoundedIcon className = "text-error mr-4" fontSize = "large" />{" "}
          <p className = "text-lg"> Produto Fora de Estoque</p>
        </div>
      </>
    );
  }
}

Это происходит только при активированном строгом режиме, но почему?

Отвечает ли это на ваш вопрос? Мой компонент React рендерится дважды из-за строгого режима

Michał Turczyn 23.02.2024 19:28

Спасибо, друг, я знаю, что это происходит из-за строгого режима, но я просто хочу знать, почему в этом случае. В большинстве случаев это происходит на useEffects, в основном из-за неправильного использования setTimeout или отсутствия функции очистки. Но в данном случае я не понимаю, почему у него такой побочный эффект, и именно это я действительно хочу понять. Большинство людей просто советуют мне отключить его, но это очень помогает обнаружить утечки памяти и пропустить использование вызовов API.

Kobra 23.02.2024 19:58
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
2
71
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Для тех, у кого такая же проблема, как у меня.

Происходящее немного сбивает с толку, но попробуйте проследить.

Я менял состояние, используя changeCartItemQuantity внутри функции setState, а затем возвращал новые cartItems, которые уже были обновлены.

Я не понимаю, почему функция выполняется дважды, но просто сделайте ее простой, и все будет в порядке, только не пытайтесь создавать внутри сложные функции setStates

Или просто убрать Строгий режим, но не рекомендую

Другие вопросы по теме