mui / material-ui

Material UI: Comprehensive React component library that implements Google's Material Design. Free forever.
https://mui.com/material-ui/
MIT License
93.98k stars 32.28k forks source link

theme.palette.mode is wrong in first render #43907

Open croraf opened 1 month ago

croraf commented 1 month ago

Steps to reproduce

https://codesandbox.io/p/sandbox/theme-colorscheme-first-render-forked-gk3rsw?file=%2Fsrc%2FDemo.tsx

I set up MUI with a <ThemeProvider theme={theme}> with

const theme = createTheme({
  colorSchemes: {
    dark: {...},
    light: {...}
}})
  1. ckick the toggle button to set the mode to dark (verify local storage that it gets mui-mode=dark
  2. refresh the preview
  3. notice the logs in the terminal for console.log(theme.palette.mode)

Current behavior

Even though my local storage variable is set to mui-mode=dark this logs light (then immediately after dark).

Expected behavior

Why can't MUI's ThemeProvider load the mui-mode from localStorage before the first render of its children?

Context

I get some toasts from react-toastify library pop up immediately on the first render which would then pop up with the wrong color.

Your environment

Chromium 129

npx @mui/envinfo System: OS: Linux 6.5 Ubuntu 22.04.4 LTS 22.04.4 LTS (Jammy Jellyfish) Binaries: Node: 18.12.1 - ~/.nvm/versions/node/v18.12.1/bin/node npm: 8.19.2 - ~/.nvm/versions/node/v18.12.1/bin/npm pnpm: Not Found Browsers: Chrome: 129.0.6668.58 npmPackages: @emotion/react: ^11.13.3 => 11.13.3 @emotion/styled: ^11.13.0 => 11.13.0 @mui/base: 5.0.0-beta.58 @mui/core-downloads-tracker: 6.0.2 @mui/icons-material: ^6.0.2 => 6.0.2 @mui/lab: ^6.0.0-beta.9 => 6.0.0-beta.9 @mui/material: ^6.0.2 => 6.0.2 @mui/private-theming: 6.0.2 @mui/styled-engine: 6.0.2 @mui/styles: ^6.0.2 => 6.0.2 @mui/system: ^6.0.2 => 6.0.2 @mui/types: 7.2.16 @mui/utils: 5.16.6 @mui/x-charts: ^7.16.0 => 7.16.0 @mui/x-charts-vendor: 7.16.0 @mui/x-date-pickers: ^7.18.0 => 7.18.0 @mui/x-internals: 7.16.0 @mui/x-tree-view: ^7.16.0 => 7.16.0 @types/react: ^18.3.5 => 18.3.5 react: ^18.3.1 => 18.3.1 react-dom: ^18.3.1 => 18.3.1 typescript: ^5.5.4 => 5.5.4

Search keywords: theme theming

sai6855 commented 1 month ago

@croraf have you set mode: dark in createTheme? Refer to doc for more info https://mui.com/material-ui/customization/dark-mode/#dark-mode-only

croraf commented 1 month ago

@sai6855 that would make the app use the dark mode as default mode. I don't want to change the default.

I want the mode, that the user had after leaving the app in the last session, to be present for current session. This does happen, but the first render logs light.


I now updated the sandbox with the log to the const { mode } = useColorScheme(); and I guess it doesn't immediately register that the mode is set to dark or light or system but it shows undefined.


I guess there is some need to do it like this, but this is unfortunate, as I don't see why not synchronously check the local-storage and show that as an initial state?

oliviertassinari commented 1 month ago

@croraf Could you make the sandbox public? Thanks

siriwatknp commented 1 month ago

I'll try useSyncExternalStore to see if it improves the first calculation of the mode.