Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

278
Views
Reacciona los cambios en el valor de retorno del gancho personalizado y, sin embargo, el componente usa el valor de retorno inicial

Creé un enlace personalizado que detecta y devuelve dinámicamente el tema de color del sistema. El enlace personalizado detecta correctamente cada cambio y establece el valor en consecuencia. Pero el componente que usa el enlace personalizado siempre muestra el valor inicial devuelto por el enlace, aunque se vuelve a representar en cada cambio de tema.

Realmente agradecería si alguien puede explicar por qué sucede esto y puede sugerir una solución adecuada.
Gracias por adelantado.

useThemeDetector.js

 import { useState, useEffect } from 'react'; const useThemeDetector = () => { // media query const mq = window.matchMedia("(prefers-color-scheme: dark)"); const [ theme, setTheme ] = useState(mq.matches ? 'dark' : 'light'); const themeListener = e => { setTheme( e.matches ? 'dark' : 'light' ); }; useEffect(() => { mq.addListener(themeListener); return () => { mq.removeListener(themeListener); }; }, [theme]); // debug output, shows correct value console.log(`theme: ${theme}, from hook`); return theme; }; export default useThemeDetector;

Aplicación.js

 import Board from './components/Board'; import { useState } from 'react'; import { ThemeContext } from './Context'; import useThemeDetector from './customHooks/useThemeDetector'; const themes = { 'light': { 'bgColor': "#fff", 'fgColor': "#000" }, 'dark': { 'bgColor': "#282c34", 'fgColor': "#61dafb" } }; function App() { const sysTheme = useThemeDetector(); const [ theme, setTheme ] = useState(sysTheme); const [ bgColor, setBgColor ] = useState(themes[theme]['bgColor']); const [ fgColor, setFgColor ] = useState(themes[theme]['fgColor']); // debug output, shows initial value on every render console.log(`theme: ${theme}, from App`); const toogleTheme = () => { if (theme === 'light') { setTheme('dark'); setBgColor(themes['dark']['bgColor']); setFgColor(themes['dark']['fgColor']); } else { setTheme('light'); setBgColor(themes['light']['bgColor']); setFgColor(themes['light']['fgColor']); } }; const style = { // styles... }; return ( <ThemeContext.Provider value={{ theme, toogleTheme }}> <div className="App" style={style} > <Board /> </div> </ThemeContext.Provider> ); } export default App;
about 4 years ago · Santiago Gelvez
1 answers
Answer question

0

El problema es que está usando useState dos veces. Ya existe una variable de estado dentro del gancho personalizado:

 const [ theme, setTheme ] = useState(mq.matches ? 'dark' : 'light');

Pero luego, en App.js , está agregando otra variable de estado distinta:

 const [ theme, setTheme ] = useState(sysTheme);

Esa segunda variable es diferente a la que está dentro del enlace personalizado, por lo que simplemente se inicializa con el valor que tenía sysTheme cuando se inicializó.

En su lugar, puedes hacer algo como esto:

  • Deshazte de esta línea const [ theme, setTheme ] = useState(sysTheme);
  • En el enlace personalizado, devuelve la tupla [theme, setTheme]
  • En App.js haz const [theme, setTheme] = useThemeDetector(); ...y deje el resto del código como está, ya que se refiere a esos nombres.

Sin embargo, puede haber otros problemas con su gancho personalizado. Parece que agregará más y más detectores de eventos cada vez que cambie el valor del theme . Probablemente solo debería agregar un detector de eventos si ya no hay ninguno. No estoy 100% seguro de esto, pero sin duda lo probaría si fuera tú.

ACTUALIZACIÓN: Creo que deberías hacer que tu gancho useEffect dependa de setTheme y no de theme .

about 4 years ago · Santiago Gelvez Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!