简体   繁体   中英

React TypeScript How to attach an event listener to window.matchMedia

When the react page loads it detects if the user has set dark mode in their operating system

const darkMode = window.matchMedia('(prefers-color-scheme: dark)').matches;

and then renders one of two images depending on the result

import logoDark from '../images/logoDark.svg';
import logoLight from '../images/logoLight.svg';

<img src={darkMode ? logoDark : logoLight} />

But if the user changes mode after the page has loaded the image isn't updated, how do I add an event listener to window.matchMedia ?

I have tried with..

  darkMode.addEventListener( "change", (e) => {
    darkMode = e.matches;
    console.log(e.matches) // true / false
  });

but I get the error Type 'boolean' is not assignable to type 'MediaQueryList'.ts(2322)

UDATE : Working Code

import React, {useContext} from "react";
import Context from '../components/context';
import logoDark from '../images/logoDark.svg';
import logoLight from '../images/logoLight.svg';

const Home: React.FC = () => {
  const darkMode = window.matchMedia('(prefers-color-scheme: dark)');   
  darkMode.addEventListener( "change", (e) => {
    if (e.matches) {
      setGlobal({...global, mode: true})
    } else {
      setGlobal({...global, mode: false})
    }
  });
  return (
  <img src={global.mode ? logoDark : logoLight} />
}

export default Home;

darkMode is a state that has type value if I understand correctly. And if it is not it should be in state in order to manipulate it. The type e.matches returns is a Boolean as you see. So, you need to change the darkMode type to Boolean..

And setState, base on the condition. I do not have the complete code so, I will not make guesses. If you paste more code samples I can help more..

You are adding eventListener on matches, which is boolean. You have to do it like below code:

 var darkMode = window.matchMedia('(prefers-color-scheme: dark)'); darkMode.addEventListener( "change", (e) => { if (e.matches) { //Perform your action for dark } else { //Perform other action } }) 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM