Implementing a useColorScheme Hook in React
This challenge asks you to implement a custom React hook, useColorScheme, that detects and responds to the user's preferred color scheme (light or dark mode) based on the prefers-color-scheme media query. This hook is useful for dynamically adjusting your application's theme based on the user's system settings, providing a more personalized and accessible experience.
Problem Description
You need to create a React hook called useColorScheme that returns the current preferred color scheme of the user's operating system. The hook should:
- Detect the Color Scheme: Utilize the
prefers-color-schememedia query to determine whether the user prefers "light" or "dark" mode. - React to Changes: Listen for changes in the user's preferred color scheme and re-render the component using the hook whenever the scheme changes.
- Return the Scheme: Return a string representing the current color scheme: either "light" or "dark".
- Handle Initial Load: Provide an initial value while the media query is being evaluated on the first render. A reasonable initial value is "light".
Expected Behavior:
- On initial render, the hook should return "light" while the media query is being evaluated.
- When the user changes their system's color scheme (e.g., through their operating system settings), the hook should re-render the component and return the new color scheme ("light" or "dark").
- The hook should not cause unnecessary re-renders.
Edge Cases to Consider:
- The media query might not be immediately available on initial load.
- The user might change their color scheme outside of the React application (e.g., in their operating system settings).
Examples
Example 1:
Input: User's system is set to "light" mode.
Output: "light"
Explanation: The hook detects the user's preference for light mode and returns "light".
Example 2:
Input: User's system is set to "dark" mode.
Output: "dark"
Explanation: The hook detects the user's preference for dark mode and returns "dark".
Example 3: (Edge Case - Initial Load)
Input: Initial render, user's system color scheme is being evaluated.
Output: "light"
Explanation: The hook returns "light" as an initial value while waiting for the media query result. After the query resolves, it will update to the correct value.
Constraints
- The solution must be written in TypeScript.
- The hook must be implemented using React's
useStateanduseEffecthooks. - The hook should be efficient and avoid unnecessary re-renders.
- The hook should not rely on external libraries.
- The returned value must be a string: either "light" or "dark".
Notes
- You can use
window.matchMediato access theprefers-color-schememedia query. - Consider using a callback function to handle changes in the media query.
- Think about how to handle the initial state of the hook before the media query is evaluated.
- Focus on creating a clean, readable, and maintainable hook. Proper type annotations are expected.