ایجاد یک سایت چند قالبی (دارک و لایت) در ری اکت

بعد از مدت ها برگشتم . این بار با یک ویدئو . دوست داشتم که تجربه ایجاد یک سایت با دو قالب دارک و لایت و نحوه پیاده سازی اون رو در ری اکت با هم کار کنیم . خوب قبل از اینکه ویدئو رو ببیند کمی صحبت کنیم طبق علاقه شخصی خودم و دلایل منطقی (یا حتی غیر منطقی و تعصبی) از context api استفاده کردم. در کنار اون ، متریال رو نصب کردم (material-ui نسخه 4.2) که با پروایدری که داره بتونیم قالب رو کامل تغییر بدیم . خوب توی این راه به مشکلاتی خوردم ، چون هنوز داکیومنت جدید متریال رو کامل نخوندم و به همین دلیل در تابع createMuiTheme به مشکلاتی خوردم و برطرف کردم . ممنون میشم نظرتون رو بدونم کد فایل ها رو بعد از فیلم قرار دادم . https://www.aparat.com/v/eEPAX state.jsimport React, {createContext, useContext, useReducer} from 'react'; export const StateContext = createContext(); export const StateProvider = ({reducer, initialState, children}) =>( <StateContext.Provider value={useReducer(reducer, initialState)}> {children} </StateContext.Provider> ); export const useStateValue = () => useContext(StateContext);MaterialUIProvider.jsimport {createMuiTheme} from '@material-ui/core/styles'; import purple from '@material-ui/core/colors/purple'; import green from '@material-ui/core/colors/green'; const primary = green[500]; const accent = purple['A200']; const light = { primary: { main: primary }, secondary: { main: accent }, } const dark = { primary: { main: accent }, secondary: { main: primary }, } export const lightTheme = createMuiTheme({ palette: light, }); export const darkTheme = createMuiTheme({ palette: dark, });Login.jsimport React, {useEffect} from 'react'; import Avatar from '@material-ui/core/Avatar'; import Button from '@material-ui/core/Button'; import CssBaseline from '@material-ui/core/CssBaseline'; import TextField from '@material-ui/core/TextField'; import FormControlLabel from '@material-ui/core/FormControlLabel'; import Checkbox from '@material-ui/core/Checkbox'; import Link from '@material-ui/core/Link'; import Grid from '@material-ui/core/Grid'; import Box from '@material-ui/core/Box'; import LockOutlinedIcon from '@material-ui/icons/LockOutlined'; import Typography from '@material-ui/core/Typography'; import {makeStyles} from '@material-ui/core/styles'; import Container from '@material-ui/core/Container'; import LightButton from "@material-ui/icons/Highlight" import DarkButton from "@material-ui/icons/HighlightOutlined" import {useStateValue} from "./state"; import IconButton from "@material-ui/core/IconButton/IconButton"; function MadeWithLove() { return ( <Typography variant="body2" color="textSecondary" align="center"> {'Built with love by the '} <Link color="inherit" href="https://material-ui.com/"> Material-UI </Link> {' team.'} </Typography> ); } const useStyles = makeStyles(theme => ({ '@global': { body: { backgroundColor: theme.palette.common.white, }, }, paper: { marginTop: theme.spacing(8), display: 'flex', flexDirection: 'column', alignItems: 'center', }, avatar: { margin: theme.spacing(1), backgroundColor: theme.palette.secondary.main, }, form: { width: '100%', // Fix IE 11 issue. marginTop: theme.spacing(1), }, submit: { margin: theme.spacing(3, 0, 2), }, })); export default function SignIn() { const classes = useStyles(); const [{theme}, dispatch] = useStateValue(); return ( <Container component="main" maxWidth="xs"> <CssBaseline/> <div className={classes.paper}> {theme === "light" && <IconButton ={() => { dispatch({ type: "changeTheme", theme: "dark" }) }}> <LightButton/> </IconButton> } {theme === "dark" && <IconButton ={() => { dispatch({ type: "changeTheme", theme: "light" }) }}> <DarkButton/> </IconButton> } <Avatar className={classes.avatar}> <LockOutlinedIcon/> </Avatar> <Typography component="h1" variant="h5"> Sign in </Typography> <form className={classes.form} noValidate> <TextField variant="outlined" margin="normal" required fullWidth id="email" label="Email Address" name="email" autoComplete="email" autoFocus /> <TextField variant="outlined" margin="normal" required fullWidth name="password" label="Password" type="password" id="password" autoComplete="current-password" /> <FormControlLabel control={<Checkbox value="remember" color="primary"/>} label="Remember me" /> <Button type="submit" fullWidth variant="contained" color="primary" className={classes.submit} > Sign In </Button> <Grid container> <Grid item xs> <Link href="#" variant="body2"> Forgot password? </Link> </Grid> <Grid item> <Link href="#" variant="body2"> {"Don't have an account? Sign Up"} </Link> </Grid> </Grid> </form> </div> <Box mt={5}> <MadeWithLove/> </Box> </Container> ); }App.jsimport React from 'react'; import Login from "./Login"; import {StateContext, StateProvider} from "./state"; import {darkTheme, lightTheme} from "./MaterialUIProvider"; import {ThemeProvider} from '@material-ui/styles'; export default function SignIn() { const initialState = { theme: 'light' } const reducer = (state, action) => { switch (action.type) { case 'changeTheme': return { ...state, theme: action.theme }; default: return state; } }; return ( <StateProvider initialState={initialState} reducer={reducer}> <StateContext.Consumer> {value=> { const theme=value[0].theme return ( <ThemeProvider theme={theme === 'light' ? lightTheme : darkTheme}> <Login/> </ThemeProvider> ) } } </StateContext.Consumer> </StateProvider> ); }