• Что бы вступить в ряды "Принятый кодер" Вам нужно:
    Написать 10 полезных сообщений или тем и Получить 10 симпатий.
    Для того кто не хочет терять время,может пожертвовать средства для поддержки сервеса, и вступить в ряды VIP на месяц, дополнительная информация в лс.

  • Пользаватели которые будут спамить, уходят в бан без предупреждения. Спам сообщения определяется администрацией и модератором.

  • Гость, Что бы Вы хотели увидеть на нашем Форуме? Изложить свои идеи и пожелания по улучшению форума Вы можете поделиться с нами здесь. ----> Перейдите сюда
  • Все пользователи не прошедшие проверку электронной почты будут заблокированы. Все вопросы с разблокировкой обращайтесь по адресу электронной почте : info@guardianelinks.com . Не пришло сообщение о проверке или о сбросе также сообщите нам.

Three React MUI commandments

Sascha Оффлайн

Sascha

Заместитель Администратора
Команда форума
Администратор
Регистрация
9 Май 2015
Сообщения
1,480
Баллы
155

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

is a popular React library for building feature-rich UI. There are many great competitors like

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

,

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

, and so on. However, MUI is still my preferred choice when I need to create a robust enterprise frontend application. The library has

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

,

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

, and strong accessibility out of the box.

Because MUI is powerful, things can often get messy. You’ve probably experienced this frustration firsthand:


Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.



I’ve been using the library since version 4 on many of my projects. In this article, I share 3 quick tips I learned the hard way. So you can save hours of refactoring and develop more maintainable and testable components:


Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.



Okay, let’s get started cleaning up the mess. Here’s the first rule.

Rule number uno - theme it or leave it


Always start exploring customization possibilities from

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

.

The global theme config centralizes styles for all MUI components, ensuring consistent styling throughout the entire app. That’s why, when you make some adjustment to the Material UI component inside the global theme, it will be applied to all the instances of this component across the app.

Let’s take a button as an example. MUI’s default button is in Material Design 2 style:


Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.



But what if we want it to match GitHub’s Primer looks:


Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.



For that, we create a new theme config and customize the MuiButton component through it:


Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.




// theme.tsx

import { createTheme } from "@mui/material";

export const theme = createTheme({
components: {
// Name of the component
MuiButton: {
styleOverrides: {
root: {
textTransform: "none",
boxShadow: "none",
padding: "0 12px",
height: 32,
borderRadius: 6,
backgroundColor: "rgb(45, 164, 78)",
border: "1px solid rgba(27, 31, 36, 0.15)",
},
},
},
},
});



NOTE: Always use colors from the

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

. Don’t put them directly as strings into your theme config. I did to avoid a complex setup and focus strictly on the rule.
Don’t forget to use ThemeProvider to

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

:


Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.




// main.tsx

//...
createRoot(document.getElementById("root")!).render(
<StrictMode>
<CssBaseline />
<ThemeProvider theme={theme}>
<App />
</ThemeProvider>
</StrictMode>
);




But what if the theme doesn’t give you enough flexibility? That’s where our second rule comes in.

Rule number two - styled component is what you do


Did you carefully investigate

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

and couldn’t find the desired one for the component you want to customize? It’s time to take the next step - create a styled component.

Let’s proceed with the button. Assume we want to have 2 shapes: round and square. By default, MUI doesn’t provide us with the shape property, but we can easily add it by creating a new styled component:


Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.




// button.styled.ts

import {
Button as MuiButton,
styled,
type ButtonProps as MuiButtonProps,
} from "@mui/material";

// Determines whether a given prop should be forwarded to the underlying DOM element.
const shouldForwardProp = (prop: string) => {
if (!prop || typeof prop !== "string") return false;

return !prop.trim().startsWith("$");
};

type ButtonProps = MuiButtonProps & {
$shape?: "round" | "square";
};

export const Button = styled(MuiButton, { shouldForwardProp })<ButtonProps>(
({ $shape = "square" }) => {
const shapeStyle = {
round: {
borderRadius: 100,
},
square: {},
};

return shapeStyle[$shape];
}
);




Important takeaways from the code above:

  1. Always add dollar $ or another valid sign to the beginning of your custom property. Then use

    Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

    utility function to prevent the custom prop from being forwarded to the underlying DOM element. This stops MUI from throwing “Invalid attribute name: shape” in the console.

    Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

  2. Use styled function from @mui/material package, not from @emotion/styled. Emotion has a different syntax and is not aware of all MUI components and internal structures, which Material UI adds on top of Emotion. That’s why you may run into errors or unsupported cases if you try to customize the MUI component directly with Emotion.

Now, make sure you import your styled Button component instead of MUI’s default one everywhere you use it:


Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.




// App.tsx

import { Stack } from "@mui/material";

// Import custom styled component, not MUI's one
**import { Button } from "./button.styled";**

function App() {
return (
<Stack p={2} spacing={1} sx={{ width: 100 }}>
<Button variant="contained">Square</Button>
<Button variant="contained" $shape="round">
Round
</Button>
</Stack>
);
}

export default App;




The result:


Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.



If the theme doesn’t cover your needs, you may also be tempted to use the sx prop. Here’s why creating a styled component works better.

Why not to use sx?



Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

is fine for quickly adding 2-3 theme-aware inline styles. But if you have more complex styling logic, consider using styled components, like I showed above. With this approach, you keep your styling and business logic separate, which improves readability and maintainability.

Sometimes customization goes beyond styling. In that case, it’s time for our third rule.

Style can’t solve? React component's the resolve


Pretend we have a requirement to add a sound effect every time a user clicks on the button. Styled components cannot achieve this, and MUI doesn’t provide any design tokens or capabilities for adding sound either.

When customization involves complex logic, we create a new React wrapper around the styled button:


Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.




// Button.tsx

import useSound from "use-sound";
import buttonSound from "../public/button.mp3";
import type { FC } from "react";
import { type ButtonProps, Button as ButtonStyled } from "./button.styled";

export const Button: FC<ButtonProps> = (props) => {
const [play] = useSound(buttonSound);

return <ButtonStyled {...props} onClick={() => play()}></ButtonStyled>;
};



NOTE: To play sound, I use

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

. Find sound effects on

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

.
Now use the new button component inside your app:


Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.




// App.tsx

import { Stack } from "@mui/material";

// Import custom wrapper component, not MUI's or styled one
**import { Button } from "./Button";**

function App() {
return (
<Stack p={2} spacing={1} sx={{ width: 100 }}>
<Button variant="contained">Square</Button>
<Button variant="contained" $shape="round">
Round
</Button>
</Stack>
);
}

export default App;




Now that you’ve seen all three rules in action, let’s wrap it up.

Conclusion


Congratulations! 🎉

Now you know how to keep your MUI-based design system tidy. You’ve learned:

  1. Why and how to customize components through the global theme wherever it makes sense.
  2. In what cases use styled components.
  3. In what cases you should create a separate React wrapper over the MUI component.

Without this hierarchy, you’ll end up mixing theme overrides, inline sx, and wrapper hacks in random places.

By applying these three easy-to-follow rules, you’re going to build design systems that are easy to maintain, test, and document. Your colleagues and future self will very likely appreciate it 🙂

Want more? 🔥


Check my previous article “

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

” where I teach good old React MVVM with a modern tech stack.


Creating content like this is not an easy ride, so I hope you’ll hit that like button and drop a comment. As usual, constructive feedback is always welcome!

🔗

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.



📰 Read me on the platform of your choice:

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

,

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.



Till next time! 👋



Источник:

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

 
Вверх Снизу