Discussion: are callbacks to withStyles always the best way to obtain the theme?
See original GitHub issueThis question occurred to me while thinking about #9192, and I’ll repost part of my comment there:
If one is not developing reusable MUI components, but instead making an app, is there any advantage to using withStyles
with a callback, vs. exporting your theme from a module and then importing it everywhere that you want to use it? For example,
// src/theme.ts
import createMuiTheme from 'material-ui/styles/createMuiTheme';
import { red, purple } from 'material-ui/colors';
export default createMuiTheme({
palette: {
primary: red,
secondary: purple,
},
});
// src/index.tsx
import * as React from 'react';
import App from './App';
import theme from './theme';
ReactDOM.render(
<MuiThemeProvider theme={theme}>
<App />
</MuiThemeProvider>,
document.getElementById('root')
);
// src/component.ts
import * as React from 'react';
import { withStyles } from 'material-ui/styles';
import theme from './theme';
export default withStyles({
root: {
margin: theme.spacing.unit * 3,
},
})(...);
This is particularly relevant to TypeScript for 2 reasons:
- it seems impossible to solve #9192 in a well-typed way with the callback approach
- callbacks interfere with type inference because of this TypeScript issue. If you look through the
material-ui
issue tracker you’ll find that this has been the source of all kinds of confusion. The workaround, which is not obvious at all, requires annotatingwithStyles
with a union of all your class keys, e.g.withStyles<'root'| | 'docked' | 'paper' | 'modal'>(/* ... */)
. Various complex solutions have been proposed for this, notably #8829 and #9105.
Simply exporting a global theme and then importing it where you need it rather than using callbacks everywhere magically makes all these problems melt away.
It seems like the advantage of using a callback is that it makes your components more modular; you can ship them as a library and others can use them within any MuiThemeProvider
. But in many cases people aren’t making reusable libraries, they’re making an app, in which case it seems like it’s fine to just reference a global theme.
Issue Analytics
- State:
- Created 6 years ago
- Reactions:5
- Comments:25 (25 by maintainers)
Top GitHub Comments
This gives a natural way to accomplish a feature many have been asking for: styles that depend on props. Just move the definition of
styles
inside the component.I have another iteration It gives the class names by inferr, supports the them via context, expose type that you can use separately. (See the
style: typeof Styled.style
)How to use: