This question already has answers here:
Internal implementation of "makeStyles" in React Material-UI?
(2 answers)
Closed 1 year ago.
I just started learning React material-ui and I found this makeStyles function, and they said it returns a Hook.
I remember from React hooks that a custom hook is made by wrapping a built-in hook. I tried looking inside makeStyles, and it has some interoperability and some css-in-javascript pattern.
I am really fed up with rules coming over and over again. For now can someone please tell me what is this makeStyle function and perhaps suggest a better approach to reading about material-ui.
Thank you good people of Stack Overflow.
If you are familiar with the older version of Material-UI, you might have used withStyles, to use your custom styles in MUI components.
withStyles is just a HOC(Higher Order Component), used as a wrapper, to assign the classes prop to your component. You can furthur use the classes object to assign specific classes to your DOM or MUI elements in your component.
makeStyles is just a successor, which returns a hook(to access the custom classes). Now this is only a modern-react way of doing things in order to avoid HOCs.
MUI v3.9.3
import { withStyles } from '#material-ui/core/styles';
const styles = {
root: {
backgroundColor: 'red'
},
};
class MyComponent extends React.Component {
render () {
return <div className={this.props.classes.root} />;
}
}
export default withStyles(styles)(MyComponent);
MUI v4.9.5
import React from 'react';
import { makeStyles } from '#material-ui/core/styles';
const useStyles = makeStyles({
root: {
backgroundColor: 'red'
},
});
export default function MyComponent(props) {
const classes = useStyles(props);
return <div className={classes.root} />;
}
Related
When trying to override the padding property in TextField input using MakeStyles, a new class is created called .makeStyles-input which is priorotized under MuiOutlinedInput-root class.
How do I inject a property into the input class (not depending on whether the OutlineInput or FilledInput component is used, and without using the important css tag)?
import { TextField } from '#mui/material';
import { makeStyles } from '#mui/styles';
const useStyles = makeStyles({
input: {
padding: 0,
},
});
function CustomTextField(props) {
const classes = useStyles();
return (
<TextField
InputProps={{
classes: {
root: classes.input,
},
}}
{...props}
/>
);
}
I don't believe that MUI 4 allows for that level of customization on their TextField component.
My recommendation comes from the MUI (v4) docs, I would be to use the InputBase component to customize, or use one of the three input variants that do allow for more customization, namely the OutlinedInput, FilledInput or Input components.
TextField is an abstraction on top of those components, so you lose a bit of customization due to the fact that a lot of the props are decided for you.
Look at the Google Maps input form demo on MUI, it's a good starter for what you're trying to do.
I'm using MUI v5 and decided to migrate from makeStyles to styled() utility function. I have this styled div:
import { styled } from "#mui/system";
export const WelcomeDiv = styled("div")({
background: "blue",
});
I try to import it use it this way:
return (
<WelcomeDiv>
</WelcomeDiv>
);
Thing is, I've just started using typescript and not sure how to implement it.
Hello there fellow programmers.
I am currently experiencing an issue with my own styles created using makeStyles(...). What's happening is; when I import my styles constant which is exported from another module, the style block is placed before the other MUI styles which causes mine to be overriden. I have not yet been able to find any solution to this what so ever and that is why I am here today, trying to figure out how I could possibly go my ways to fix this. Here's an image that contains the order of the style blocks that is playing with my mind currently.
PLEASE NOTE: The style block that's mine is the one with the data meta of makeStyles. Another thing is, I've attempted to use StylesProvider.
IMPORTANT: This only happens when uploaded. It works just fine on localhost, but this is the outcome of being uploaded to vercel.
Here's two examples of usages:
import { Theme } from '#material-ui/core';
import { makeStyles } from '#material-ui/core/styles';
const DarkTheme = makeStyles((theme: Theme) => ({
mdButton: {
backgroundColor: "#404040"
},
}));
export default DarkTheme;
import {Button} from '#material-ui/core';
import React from "react";
import DarkTheme from 'DarkTheme';
export default function Example() {
const styles = DarkTheme();
return (
<Button className={styles.mdButton}>
Example
</Button>
)
}
Any help is appreciated, thank you in advance.
As you may know, f you have two CSS classes applied to the same element with the same degree of specificity, then the winner will be the CSS class that is defined last within the document (based on the order of the elements in the , NOT the order of the class name strings in the class attribute of the element being styled). As: Material UI v4 makeStyles exported from a single file doesn't retain the styles on refresh
So, you can change order of imports. Import Button before import style.
Let try with what is different from:
import React from "react";
import {Button} from '#material-ui/core';
import DarkTheme from 'DarkTheme';
and
import React from "react";
import DarkTheme from 'DarkTheme';
import {Button} from '#material-ui/core';
makeStyles returns a function which must be called as a React hook. So please name it in consequence.
const useDarkTheme = makeStyles((theme: Theme) => ({
mdButton: {
backgroundColor: "#404040"
},
}));
export default useDarkTheme;
https://reactjs.org/docs/hooks-intro.html
If you don't want to use hooks you can check withStyles alternative: https://material-ui.com/styles/basics/#higher-order-component-api
You can also check how CSS injection works in material-ui https://material-ui.com/styles/advanced/#css-injection-order (tl;dr: order of makeStyles calls matter).
I'm getting the following error after upgrading to MUI v4.0.2 from v3.9.x:
You must pass a component to the function returned by connect. Instead received {"propTypes":{},"displayName":"WithStyles(MyComponent)","options":{"defaultTheme":{"breakpoints":{"keys":["xs","sm","md","lg","xl"],"values":
...
MyComponent:
import { withStyles } from '#material-ui/core/styles'
const getStyles = theme => ({
fooBar: {
...
},
})
...
export default withStyles(getStyles)(MyComponent)
MyContainer:
import { connect } from 'react-redux'
import MyComponent from './MyComponent'
...
export default connect(mapStateToProps, mapDispatchToProps)(MyComponent)
How to migrate withStyles?
Version 5.0.7 and earlier of react-redux performed the following validation on the component passed to connect:
https://github.com/reduxjs/react-redux/blob/v5.0.7/src/components/connectAdvanced.js#L91
invariant(
typeof WrappedComponent == 'function',
`You must pass a component to the function returned by ` +
`${methodName}. Instead received ${JSON.stringify(WrappedComponent)}`
)
With the introduction of React.forwardRef (which is used heavily in Material-UI v4) and other features introduced in React 16.8 (hooks), it is possible to have a component type that is not a function.
More recent versions of react-redux instead use isValidElementType from the react-is package. This correctly recognizes the component types returned by forwardRef and other methods.
I believe versions 5.1 and later of react-redux should all work fine without erroneously causing the error mentioned in the question.
This is how I do it:
import { withStyles } from '#material-ui/core/styles';
Define your styles object: look at the material-ui examples for guidance
const styles => ({
root: {
display: 'flex',
}
});
Then export the component using your styles:
export default withStyles(styles)(YourComponent);
Can anyone recommend the best way to compose styled-components that need to be themed?
Here's my code: https://gist.github.com/aaronmcadam/7bfd63a6bc4cfc36f9947a449c6f494a.
I have an Avatar component which composes an Image component, which is itself a styled-component.
If I use Avatar.styled.js with <ThemeProvider>, the theme can be successfully overridden.
If I use Avatar.withTheme.js, the theme can only be overridden if I use withTheme.
Which is the preferred way of doing things like these?
from the official docs: https://github.com/styled-components/styled-components/blob/master/docs/theming.md
We export a component that takes a theme prop. The
theme you provide there is injected into your styled components via
props.theme
If you ever need to get the current theme outside styled components
(e.g. inside big components), you can use the withTheme Higher Order
Component
import { withTheme } from 'styled-components'
class MyComponent extends React.Component {
render() {
const { theme } = this.props
console.log('Current theme: ', theme);
// ...
}
}
export default withTheme(MyComponent)