Skip to content

Appearance module does not behave correctly: addChangeListener does not react to changes, useColorScheme() does not react to changes. #28823

Closed
standardnotes/app
#2905
@sannajammeh

Description

@sannajammeh

Description

The subscription of useColorScheme() and Appearance.addChangeListener() wont work. The hook returns an initial value only on component mount. Changes to the devices color scheme on Android does not provide the hook with a new value. I therefore tried to manually replicate this hook with useEffect and the Appearance module and found that Appearance.addChangeListener() when called returns "undefined", not type EventSubscription. The listener function provided to Appearance.addChangeListener() never gets called.

I have only tested this on Android so I am not aware if this is also an issue on iOS.

React Native version:

System:
    OS: Windows 10 10.0.17763
    CPU: (16) x64 Intel(R) Core(TM) i7-5960X CPU @ 3.00GHz
    Memory: 15.05 GB / 31.92 GB
  Binaries:
    Node: 10.16.2 - C:\Program Files\nodejs\node.EXE
    Yarn: 1.19.2 - C:\Program Files (x86)\Yarn\bin\yarn.CMD
    npm: 6.14.4 - C:\Program Files\nodejs\npm.CMD
    Watchman: Not Found
  SDKs:
    Android SDK:
      API Levels: 28, 29
      Build Tools: 28.0.3, 29.0.2, 29.0.3
      System Images: android-28 | Intel x86 Atom_64, android-R | Google APIs Intel x86 Atom
      Android NDK: Not Found
  IDEs:
    Android Studio: Version  3.6.0.0 AI-192.7142.36.36.6308749
  Languages:
    Java: 1.8.0_211 - C:\Program Files\Java\jdk1.8.0_211\bin\javac.EXE
    Python: 2.7.18 - C:\Python27\python.EXE
  npmPackages:
    @react-native-community/cli: Not Found
    react: 16.11.0 => 16.11.0
    react-native: 0.62.2 => 0.62.2
  npmGlobalPackages:
    *react-native*: Not Found

Steps To Reproduce

Provide a detailed list of steps that reproduce the issue.

  1. run npx react-native init TestDark --template react-native-template-typescript
  2. Import Appearance & useColorScheme from 'react-native'
  3. copy paste the code snippet below above the return in <App /> or use the useColorScheme hook and console.log its output.
  4. Change the color scheme of the Android device and check the console for the correct values.

Expected Results

The useColorScheme hook should return the correct colorScheme when the devices colorScheme changes.
The Appearance.addChangeListener() should return type EventSubscription not undefined.
The listener callback provided to Appearance.addChangeListener(cb) should be called.

Snack, code example, screenshot, or link to a repository:

const App = () => {
  const colorScheme = useColorScheme(); // Only gives initial colorScheme, does not return new colorScheme on change.
  const [mode1, setMode1] = useState('light');
  const mode = colorScheme || 'light';

  React.useEffect(() => {
    const initialColorScheme = Appearance.getColorScheme(); // Works as expected
    setMode1(initialColorScheme || 'light');

    const listener = () => {
      console.log('called'); // Never fires
      const colorScheme1 = Appearance.getColorScheme();
      setMode1(colorScheme1 || 'light');
    };

    const subscription = Appearance.addChangeListener(listener);
    console.log('App -> subscription', subscription); // logs as undefined
    return () => {
      Appearance.removeChangeListener(listener);
    };
  }, []);
  return (
   // jsx
  )
}

Here is a GIF of the app created with npx react-native init NAME --template react-native-template-typescript command. Look for Mode: dark (useColorScheme() and Mode_1 (useEffect & Appearance module). https://gyazo.com/d4ddb35bf689b3c8926be2f613714f73

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions