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

بعد از مدت ها برگشتم . این بار با یک ویدئو .
دوست داشتم که تجربه ایجاد یک سایت با دو قالب دارک و لایت و نحوه پیاده سازی اون رو در ری اکت با هم کار کنیم .
خوب قبل از اینکه ویدئو رو ببیند کمی صحبت کنیم
طبق علاقه شخصی خودم و دلایل منطقی (یا حتی غیر منطقی و تعصبی) از context api استفاده کردم. در کنار اون ، متریال رو نصب کردم (material-ui نسخه 4.2) که با پروایدری که داره بتونیم قالب رو کامل تغییر بدیم . خوب توی این راه به مشکلاتی خوردم ، چون هنوز داکیومنت جدید متریال رو کامل نخوندم و به همین دلیل در تابع createMuiTheme به مشکلاتی خوردم و برطرف کردم .
ممنون میشم نظرتون رو بدونم
کد فایل ها رو بعد از فیلم قرار دادم .
state.js
import 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.js
import {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.js
import 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.js
import 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>
);
}
مطلبی دیگر از این انتشارات
چطور logic پروژمون رو بین React و React Native باید share کنیم؟
مطلبی دیگر از این انتشارات
خلاص شدن از شر مسیر دهی های طولانی در reactjs
مطلبی دیگر از این انتشارات
دومین رویداد جامعه ریاکت ایران در دانشگاه شهید بهشتی (26-2-98)