#reactjs #material-ui #react-material
#reactjs #материал-пользовательский интерфейс #react-материал
Вопрос:
У меня есть два родительских проекта react и общий проект (содержит общий компонент, такой как верхний и нижний колонтитулы)
У меня есть тема материала, определенная в родительском и настроенная стандартным способом MuiThemeProvider
.
Однако этот объект темы доступен внутри компонентов, определенных в Parent, но не в share project common.
Предложения приветствуются.
Добавлено ниже более подробная информация 30 октября 2020 г.
Родительский компонент
import React from "react";
import "./App.css";
import { BrowserRouter, Switch, Route } from "react-router-dom";
import themeDefault from "./CustomTheme.js";
import { MuiThemeProvider } from "@material-ui/core/styles";
import { createMuiTheme } from "@material-ui/core/styles";
import Dashboard from "./containers/Dashboard/Dashboard";
import { Footer, Header } from "my-common-react-project";
function App() {
const routes = () => {
return (
<BrowserRouter>
<Switch>
<Route exact path="/" component={Dashboard} />
</Switch>
</BrowserRouter>
);
};
return (
<MuiThemeProvider theme={createMuiTheme(themeDefault)}>
<div className="App">
<Header
logo="some-logo"
userEmail={"test@email"}
/>
... app components here..
<Footer />
</div>
</MuiThemeProvider>
);
}
export default App;
Общий компонент
import React from "react";
import {
Box,
AppBar,
Toolbar,
Typography,
} from "@material-ui/core/";
import styles from "./Header.styles";
import PropTypes from "prop-types";
const Header = (props) => {
const classes = styles();
const { options, history } = props;
const [anchorEl, setAnchorEl] = React.useState(null);
const handleCloseMenu = () => {
setAnchorEl(null);
};
const goto = (url) => {
history.push(url);
};
return (
<Box component="nav" className={classes.headerBox}>
<AppBar position="static" className={classes.headerPart}>
<Toolbar className={classes.toolBar}>
{localStorage amp;amp; localStorage.getItem("isLoggedIn") amp;amp; (
<>
{options amp;amp;
options.map((option) => (
<Typography
key={option.url}
variant="subtitle1"
className={classes.headerLinks}
onClick={() => goto(option.url)}
>
{option.name}
</Typography>
))}
</>
)}
</Toolbar>
</AppBar>
</Box>
);
};
Header.propTypes = {
options: PropTypes.array
};
export default Header;
Стиль общего компонента
import { makeStyles } from "@material-ui/core/styles";
export default makeStyles((theme) => ({
headerPart: {
background: "white",
boxShadow: "0px 4px 15px #00000029",
opacity: 1,
background: `8px solid ${theme.palette.primary.main}`
borderTop: `8px solid ${theme.palette.primary.main}`
}
}));
Родительский компонент определен theme.palette.primary.main
, скажем, как красный цвет, и я ожидаю, что он будет применен в заголовке, но он выбирает другой объект темы (по умолчанию), который имеет theme.palette.primary.main
синий цвет.
В результате мой заголовок будет синего цвета, а тело — цвета чтения.
Любое предложение, как настроить этот объект темы, чтобы заголовок тоже выбирал theme.palette.primary.main
из родительского объекта темы.
Комментарии:
Ответ №1:
вот ответ для mui V5
import { useTheme } from '@mui/material/styles' // /! I fixed a typo from official doc here
function DeepChild() {
const theme = useTheme();
return <span>{`spacing ${theme.spacing}`}</span>;
}
Взято из документации mui
Ответ №2:
Вы можете использовать либо useTheme
или withTheme
для внедрения объекта темы в любые вложенные компоненты внутри ThemeProvider
.
- Используйте
useTheme
хук в функциональных компонентах - Используйте
withTheme
HOC в компонентах на основе классов (которые не могут использовать hook)
function DeepChild() {
const theme = useTheme<MyTheme>();
return <span>{`spacing ${theme.spacing}`}</span>;
}
class DeepChildClass extends React.Component {
render() {
const { theme } = this.props;
return <span>{`spacing ${theme.spacing}`}</span>;
}
}
const ThemedDeepChildClass = withTheme(DeepChildClass);
Живая демонстрация
Комментарии:
1. мои компоненты находятся в другом проекте react, а заголовок общего компонента использует тему по умолчанию, а не тему, которую я установил в поставщике темы. таким образом, этот подход не устранил проблему
2. @Ashutosh вы упускаете из виду, что общие компоненты нравятся
Header
илиFooter
могут быть в любых проектах, которые они хотят, пока они находятся внутриThemeProvider
на верхнем уровне приложения, они могут иметь доступ к данным темы из контекста темы, если вы хотите использовать тему по умолчанию, просто вызовитебезcreateMuiTheme()
параметров и передайте егоThemeProvider
наверх.3. @Ashutosh Вы заключили свой общий проект в any
ThemeProvider
?4. @NearHuscarl и Loi. Я просто добавил пример кода и детали для большей ясности. Заранее спасибо за помощь