0

Делаю изменение темы на React + scss. При клике на переключатель темы функция отрабатывает два раза.

Есть useState - который хранит состояние темы. Есть useEffect - который меняет переменные root. Есть функция toggleTheme - в которой меняется setTheme.

Проблема при клике на переключатель, функция toggleTheme и useEffect отрабатывают два раза.

Что было предпринято ссылка на похожий вопрос - убирал React.StrictMode и использовал старый render + собирал проект и выкладывал в "прод" на github pages. Проблема не была решена ни в одном из случаев.

index.jsx

import React from "react";
import { createRoot } from "react-dom/client";
import { HashRouter } from "react-router-dom";
import "./index.scss";
import "./assests/css/theme.css";
import { App } from "./components/App";

createRoot(document.getElementById("root")).render( <React.StrictMode> <HashRouter> <App /> </HashRouter> </React.StrictMode> );

компонент ButtonTheme.jsx - в котором описана логика переключения темы. Компонент подключается в header и в мобильном меню при медиа запросе.

import s from "./ButtonTheme.module.scss";
import cn from "classnames";
import React from "react";
import { useState, useEffect } from "react";

const ButtonTheme = () => { const [theme, setTheme] = useState("light"); // state темы

// функция для смены темы const toggleTheme = () => { setTheme(theme === "light" ? "dark" : "light"); // меняем state };

useEffect(() => { const backgroundColor = var(--background-color-${theme});

document.body.style.setProperty(&quot;--background-color&quot;, backgroundColor);

}, [theme]);

return ( <div className={cn(s.theme, "button__animation d-fl")} onClick={toggleTheme} > <input type="checkbox" className={s.customCheckbox} id="theme" name="theme" value="yes" ></input> <label htmlFor="theme"></label> </div> ); };

export { ButtonTheme };

Павел
  • 27
  • 8
  • Ну useEffect выполняется два раза из-за StrictMode, а вот почему функция два раза вызывается.. вопрос хороший) Хотя я не понимаю, зачем вам вешать событие клика на блок-обвертку вокруг инпута, если вы можете отслеживать onChange у него. – Oliver Patterson Aug 06 '23 at 17:41
  • @OliverPatterson , спасибо за ответ! Не подумал про onChange. Изменил событие с onClick на onChange - всё работает. Есть предположение как можно пофиксить проблему с двойным вызовом функции? – Павел Aug 08 '23 at 14:09

1 Answers1

0

Задача решена. Ответ в комментариях от @Oliver Patterson. Изменил событие с onClick на onChange - всё работает

<div
  className={cn(s.theme, "button__animation d-fl")}
  onChange={toggleTheme}
>
Павел
  • 27
  • 8