How do I submit Material UI Sign In example? - reactjs

I've created a SignIn component using Material UI's example.
import React from 'react';
import PropTypes from 'prop-types';
import Avatar from '#material-ui/core/Avatar';
import Button from '#material-ui/core/Button';
import CssBaseline from '#material-ui/core/CssBaseline';
import FormControl from '#material-ui/core/FormControl';
import FormControlLabel from '#material-ui/core/FormControlLabel';
import Checkbox from '#material-ui/core/Checkbox';
import Input from '#material-ui/core/Input';
import InputLabel from '#material-ui/core/InputLabel';
import LockOutlinedIcon from '#material-ui/icons/LockOutlined';
import Paper from '#material-ui/core/Paper';
import Typography from '#material-ui/core/Typography';
import withStyles from '#material-ui/core/styles/withStyles';
const styles = theme => ({
main: {
width: 'auto',
display: 'block', // Fix IE 11 issue.
marginLeft: theme.spacing.unit * 3,
marginRight: theme.spacing.unit * 3,
[theme.breakpoints.up(400 + theme.spacing.unit * 3 * 2)]: {
width: 400,
marginLeft: 'auto',
marginRight: 'auto',
},
},
paper: {
marginTop: theme.spacing.unit * 8,
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
padding: `${theme.spacing.unit * 2}px ${theme.spacing.unit * 3}px ${theme.spacing.unit * 3}px`,
},
avatar: {
margin: theme.spacing.unit,
backgroundColor: theme.palette.secondary.main,
},
form: {
width: '100%', // Fix IE 11 issue.
marginTop: theme.spacing.unit,
},
submit: {
marginTop: theme.spacing.unit * 3,
},
});
function SignIn(props) {
const { classes } = props;
return (
<main className={classes.main}>
<CssBaseline />
<Paper className={classes.paper}>
<Avatar className={classes.avatar}>
<LockOutlinedIcon />
</Avatar>
<Typography component="h1" variant="h5">
Sign in
</Typography>
<form className={classes.form}>
<FormControl margin="normal" required fullWidth>
<InputLabel htmlFor="email">Email Address</InputLabel>
<Input id="email" name="email" autoComplete="email" autoFocus />
</FormControl>
<FormControl margin="normal" required fullWidth>
<InputLabel htmlFor="password">Password</InputLabel>
<Input name="password" type="password" id="password" autoComplete="current-password" />
</FormControl>
<FormControlLabel
control={<Checkbox value="remember" color="primary" />}
label="Remember me"
/>
<Button
type="submit"
fullWidth
variant="contained"
color="primary"
className={classes.submit}
>
Sign in
</Button>
</form>
</Paper>
</main>
);
}
SignIn.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(SignIn);
Now I want to use it in a parent component with a submit handler. But I can't figure out how to execute the handler when the form in the child component is submitted
import React, { Component } from "react";
import SignIn from "../components/SignIn";
export default class Login extends Component {
constructor(props) {
super(props);
this.state = {
};
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit = async event => {
// Do Stuff
}
render() {
return (
<div className="Login">
<SignIn onSubmit={this.handleSubmit}/>
</div>
);
}
}

Change your button in the SignIn component to call the submit handler passed in through the props like so:
<Button
type="submit"
fullWidth
variant="contained"
color="primary"
className={classes.submit}
onClick={this.props.onSubmit}
>
Sign in
</Button>

Related

Type '{}' is not assignable to type 'IProps'

I am using react with formik and typescript in my project. I am using withFormik HOC in my forms, code is below
import React from "react";
//Libraries import........
import {
Container,
Box,
Link,
Grid,
Checkbox,
FormControlLabel,
TextField,
CssBaseline,
Avatar,
Typography,
makeStyles,
Theme,
} from "#material-ui/core";
import LockOutlinedIcon from "#material-ui/icons/LockOutlined";
import { Form, FormikProps, FormikValues, useFormik, withFormik } from "formik";
import * as Yup from "yup";
//Components import........
import { Button } from "#components/button";
//Interfaces ..........
interface FormValues {
email?:string,
password?:string
}
interface IProps extends FormikProps<FormValues> {
// onSubmit(e:React.FormEvent<HTMLInputElement>):void
}
const useStyles = makeStyles((theme: Theme) => ({
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),
},
}));
const Login: React.FC<IProps> = (props) => {
const classes = useStyles();
const { handleSubmit, handleBlur, handleChange, handleReset, errors } = props;
console.log(errors);
return (
<Container component="main" maxWidth="xs">
<CssBaseline />
<div className={classes.paper}>
<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"
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={8}></Box>
</Container>
);
};
export const LoginView = withFormik<IProps, FormValues>({
enableReinitialize: true,
mapPropsToValues: (props) => {
console.log(props);
return { email: "", password: "" };
},
validationSchema: Yup.object({
// email: Yup.string().required(),
}),
handleSubmit: (values) => {
console.log(values);
},
})(Login);
and then when in my project i import and use LoginView inside my pages like
import React from "react";
import { LoginView } from "#components/user/login";
const Home: React.FC = (props: any) => {
return (
<div
style={{ display: "flex", flexDirection: "column", minHeight: "100vh" }}
>
<LoginView />
</div>
);
};
export default Home;
i get an error where i write
Type '{}' is not assignable to type 'IProps'. Type '{}' is missing
the following properties from type 'FormikState': values,
errors, touched, isSubmitting, and 2 more.
First Generic Type provided to withFormik shouldn't extend from FormikValues.
Define IProps like this
interface IProps {
// onSubmit(e:React.FormEvent<HTMLInputElement>):void
}
See this https://codesandbox.io/s/stackoverflow-69143042-wlvz9

How to invoke a hook from React class component?

Question from React newbie!
I have Material UI React login form and am trying to use hook within login form. But getting invalid hook call error. No luck so far. Help please.. loginformstyles.js is the hook I am trying to use in the signin.js file.. The login page has two text fields - username and password and a Submit button.
import React 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 Container from '#material-ui/core/Container';
import { ValidatorForm, TextValidator} from 'react-material-ui-form-validator';
import { useStyles } from './loginformstyles';
export default class MyForm extends React.Component {
Copyright() {
return (
<Typography variant="body2" color="textSecondary" align="center">
{'Copyright © '}
<Link color="inherit" href="https://material-ui.com/">
Task Manager
</Link>{' '}
{new Date().getFullYear()}
{'.'}
</Typography>
);
}
handleChange (event) {
const email = event.target.value;
this.setState({ email });
}
render() {
const classes = useStyles();
return (
<Container component="main" maxWidth="xs">
<CssBaseline />
<div className={classes.paper}>
<Avatar className={classes.avatar}>
<LockOutlinedIcon />
</Avatar>
<Typography component="h1" variant="h5">
Sign in
</Typography>
<form className={classes.form} >
<TextField
variant="outlined"
margin="normal"
required
fullWidth
id="email"
label="Email Address"
name="email"
autoComplete="email"
autoFocus
validators={['required', 'isEmail']}
errorMessages={['this field is required', 'email is not valid']}
onChange={this.handleChange}
/>
<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={8}>
<this.Copyright />
</Box>
</Container>
);
}
}
import React from 'react';
import { makeStyles } from '#material-ui/core/styles';
export const useStyles = makeStyles((theme) => ({
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),
},
}));
If you just want to make this work, you could wrap the it and then expose the styles into child component, ex.
const Wrapper = ({ children }) => {
const classes = useStyles()
return children(classes)
}
and then you can do
<Wrapper>
{classes => <Copyright classes={classes} />}
</Wrapper>
Of course, this is just to get it working. In general you shouldn't mix class and hook, but as long as you can turn them into components, then you can mix and match.

React make components show in column

I am pretty new to React, and I am making my first app using material-ui, and I have managed to render the components I intend, but I haven't been able to print them stacked, they show in line:
I have tried to wrap them with div and p, and I get the same result.
This is the code of my component:
import React, { Component } from 'react';
import Button from '#material-ui/core/Button';
import classNames from 'classnames';
import PropTypes from 'prop-types';
import { withStyles } from '#material-ui/core/styles';
import Input from '#material-ui/core/Input';
import InputLabel from '#material-ui/core/InputLabel';
import InputAdornment from '#material-ui/core/InputAdornment';
import FormControl from '#material-ui/core/FormControl';
import Visibility from '#material-ui/icons/Visibility';
import VisibilityOff from '#material-ui/icons/VisibilityOff';
import IconButton from '#material-ui/core/IconButton';
const styles = theme => ({
root: {
display: 'flex',
flexWrap: 'wrap',
},
margin: {
margin: theme.spacing.unit,
},
withoutLabel: {
marginTop: theme.spacing.unit * 3,
},
textField: {
flexBasis: 200,
},
button: {
margin: theme.spacing.unit,
},
input: {
display: 'none',
},
});
class LoginModal extends Component {
state = {
password: '',
showPassword: false,
};
render() {
const { classes } = this.props
return (
<div className={classes.root}>
<h1>Welcome to My App...</h1>
<FormControl className={classNames(classes.margin, classes.textField)}>
<InputLabel htmlFor="adornment-email">eMail</InputLabel>
<Input i
d="adornment-email"
variant="filled"
/>
</FormControl>
<FormControl className={classNames(classes.margin, classes.textField)}>
<InputLabel htmlFor="adornment-password">Password</InputLabel>
<Input
id="adornment-password"
variant="filled"
type={this.state.showPassword ? 'text' : 'password'}
value={this.state.password}
endAdornment={
<InputAdornment position="end">
<IconButton
aria-label="Toggle password visibility"
onClick={this.handleClickShowPassword}
>
{this.state.showPassword ? <Visibility /> : <VisibilityOff />}
</IconButton>
</InputAdornment>
}
/>
<p>Did you forget your password?</p>
<Button color="primary" variant="contained">Login</Button>
</FormControl>
</div>
);
};
}
LoginModal.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(LoginModal);
Only the two latest components show stacked, but the rest show in line.
How can I instruct React to display components in an stacked fashion?
update your root style to:
root: {
display: 'flex',
flex-direction: column;
},
you may need to adjust other flex properties to get the alignment you want.
I found that Material-UI uses Grid components to manage responsiveness, and you can use it to arrange objects in display.
This is how I used Grid to display my objects the way I wanted:
class LoginModal extends Component {
state = {
password: '',
showPassword: false,
};
render() {
const { classes } = this.props
return (
<div className={classes.root}>
<Grid container spacing={24}>
<Grid item xs={12}>
<h1>Welcome to My App...</h1>
</Grid>
<Grid item xs={12}>
<FormControl className={classNames(classes.margin, classes.textField)}>
<InputLabel htmlFor="adornment-email">eMail</InputLabel>
<Input
id="adornment-email"
variant="filled"
/>
</FormControl>
</Grid>
<Grid item xs={12}>
<FormControl className={classNames(classes.margin, classes.textField)}>
<InputLabel htmlFor="adornment-password">Password</InputLabel>
<Input
id="adornment-password"
variant="filled"
type={this.state.showPassword ? 'text' : 'password'}
value={this.state.password}
endAdornment={
<InputAdornment position="end">
<IconButton
aria-label="Toggle password visibility"
onClick={this.handleClickShowPassword}
>
{this.state.showPassword ? <Visibility /> : <VisibilityOff />}
</IconButton>
</InputAdornment>
}
/>
<p>Did you forget your password?</p>
<Button color="primary" variant="contained">Login</Button>
</FormControl>
</Grid>
</Grid>
</div>
);
};
}
And this is the result:

Login mutation not working consistently in material-ui.

I am trying to create a sample login form in React using material-ui through graphql mutation. But the login form is not working as expected.
i am able to log in only some times, but even in those times, I do not see any data being passed via loginMutation props in console. Could some one please tell me what am i doing wrong here?
Here is the Login Component that I am trying to create
import React, { Component } from 'react';
import { AUTH_TOKEN } from '../constants';
import { graphql, compose } from 'react-apollo';
import {LOGIN_MUTATION} from "../gql/loginGQL";
import Paper from '#material-ui/core/Paper';
import Button from '#material-ui/core/Button';
import TextField from '#material-ui/core/TextField'
import PropTypes from 'prop-types';
import Avatar from '#material-ui/core/Avatar';
import CssBaseline from '#material-ui/core/CssBaseline';
import FormControl from '#material-ui/core/FormControl';
import FormControlLabel from '#material-ui/core/FormControlLabel';
import Checkbox from '#material-ui/core/Checkbox';
//import Input from '#material-ui/core/Input';
//import InputLabel from '#material-ui/core/InputLabel';
import LockIcon from '#material-ui/icons/LockOutlined';
import Typography from '#material-ui/core/Typography';
import withStyles from '#material-ui/core/styles/withStyles';
const styles = theme => ({
layout: {
width: 'auto',
display: 'block', // Fix IE11 issue.
marginLeft: theme.spacing.unit * 3,
marginRight: theme.spacing.unit * 3,
[theme.breakpoints.up(400 + theme.spacing.unit * 3 * 2)]: {
width: 400,
marginLeft: 'auto',
marginRight: 'auto',
},
},
paper: {
marginTop: theme.spacing.unit * 8,
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
padding: `${theme.spacing.unit * 2}px ${theme.spacing.unit * 3}px ${theme.spacing.unit * 3}px`,
},
avatar: {
margin: theme.spacing.unit,
backgroundColor: theme.palette.secondary.main,
},
form: {
width: '100%', // Fix IE11 issue.
marginTop: theme.spacing.unit,
},
submit: {
marginTop: theme.spacing.unit * 3,
},
});
class Login extends Component {
state = {
email: '',
password: '',
errors: null
}
render() {
const { classes } = this.props;
return (
<React.Fragment>
<CssBaseline />
<main className={classes.layout}>
<Paper className={classes.paper}>
<Avatar className={classes.avatar}>
<LockIcon />
</Avatar>
<Typography variant="headline">Sign in</Typography>
<form className={classes.form}>
<FormControl margin="normal" required fullWidth>
<TextField
id='email'
value={this.state.email}
onChange={e => this.setState({ email: e.target.value })}
type='text'
label='Your email address'
/>
</FormControl>
<FormControl margin="normal" required fullWidth>
<TextField
id='password'
value={this.state.password}
onChange={e => this.setState({ password: e.target.value })}
type='password'
label='Password'
/>
</FormControl>
<FormControlLabel
control={<Checkbox value="remember" color="primary" />}
label="Remember me"
/>
<Button
id="submit"
type="submit"
fullWidth
variant="raised"
color="primary"
className={classes.submit}
onClick={() => this._confirm()}
>
Sign in
</Button>
</form>
</Paper>
</main>
</React.Fragment>
);
}
_confirm = async () => {
const { email, password } = this.state
try{
const result = await this.props.loginMutation({
variables: {
email,
password,
},
});
console.log(result); // Here no data is being displayed !
const { jwt } = result.data.signInUser;
this._saveUserData(jwt);
this.props.history.push(`/`)
} catch(error) {
const errors = error.graphQLErrors.map(error => error.message);
this.setState({ errors });
}
}
_saveUserData = (token) => {
localStorage.setItem(AUTH_TOKEN, token)
}
}
Login.propTypes = {
classes: PropTypes.object.isRequired,
};
export default compose(
graphql(LOGIN_MUTATION, { name: 'loginMutation' }),
withStyles(styles),
)(Login)
The error was being occurred due to the Button tag. Although, it had type="submit", the form was still not being submitted due to which the input data was not being appearing in the "_confirm". I am wondering why, I must have missed something here.
For now, I created a div tag inside the Button and added onClick handler there instead of Button tag.
So, the edited code just have this small change
<Button color="primary" className = {classes.submit} variant="raised" fullWidth>
<div className="test" onClick={() => this._confirm()} >
Sign in
</div>
</Button>
Here is the full source code:
import React, { Component } from 'react';
import { AUTH_TOKEN } from '../constants';
import { graphql, compose } from 'react-apollo';
import {LOGIN_MUTATION} from "../gql/loginGQL";
import Paper from '#material-ui/core/Paper';
import Button from '#material-ui/core/Button';
import TextField from '#material-ui/core/TextField'
import PropTypes from 'prop-types';
import Avatar from '#material-ui/core/Avatar';
import CssBaseline from '#material-ui/core/CssBaseline';
import FormControl from '#material-ui/core/FormControl';
import FormControlLabel from '#material-ui/core/FormControlLabel';
import Checkbox from '#material-ui/core/Checkbox';
//import Input from '#material-ui/core/Input';
//import InputLabel from '#material-ui/core/InputLabel';
import LockIcon from '#material-ui/icons/LockOutlined';
import Typography from '#material-ui/core/Typography';
import withStyles from '#material-ui/core/styles/withStyles';
const styles = theme => ({
layout: {
width: 'auto',
display: 'block', // Fix IE11 issue.
marginLeft: theme.spacing.unit * 3,
marginRight: theme.spacing.unit * 3,
[theme.breakpoints.up(400 + theme.spacing.unit * 3 * 2)]: {
width: 400,
marginLeft: 'auto',
marginRight: 'auto',
},
},
paper: {
marginTop: theme.spacing.unit * 8,
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
padding: `${theme.spacing.unit * 2}px ${theme.spacing.unit * 3}px ${theme.spacing.unit * 3}px`,
},
avatar: {
margin: theme.spacing.unit,
backgroundColor: theme.palette.secondary.main,
},
form: {
width: '100%', // Fix IE11 issue.
marginTop: theme.spacing.unit,
},
submit: {
marginTop: theme.spacing.unit * 3,
},
});
class Login extends Component {
state = {
email: '',
password: '',
errors: null
}
render() {
const { classes } = this.props;
return (
<React.Fragment>
<CssBaseline />
<main className={classes.layout}>
<Paper className={classes.paper}>
<Avatar className={classes.avatar}>
<LockIcon />
</Avatar>
<Typography variant="headline">Sign in</Typography>
<form className={classes.form}>
<FormControl margin="normal" required fullWidth>
<TextField
id='email'
value={this.state.email}
onChange={e => this.setState({ email: e.target.value })}
type='text'
label='Your email address'
/>
</FormControl>
<FormControl margin="normal" required fullWidth>
<TextField
id='password'
value={this.state.password}
onChange={e => this.setState({ password: e.target.value })}
type='password'
label='Password'
/>
</FormControl>
<FormControlLabel
control={<Checkbox value="remember" color="primary" />}
label="Remember me"
/>
// Here is the change
<Button color="primary" className = {classes.submit}
variant="raised"fullWidth >
<div className="test" onClick={() => this._confirm()} >
Sign in
</div>
</Button>
// Change ends here
</form>
</Paper>
</main>
</React.Fragment>
);
}
_confirm = async () => {
const { email, password } = this.state
try{
const result = await this.props.loginMutation({
variables: {
email,
password,
},
});
console.log(result); // Here no data is being displayed !
const { jwt } = result.data.signInUser;
this._saveUserData(jwt);
this.props.history.push(`/`)
} catch(error) {
const errors = error.graphQLErrors.map(error => error.message);
this.setState({ errors });
}
}
_saveUserData = (token) => {
localStorage.setItem(AUTH_TOKEN, token)
}
}
Login.propTypes = {
classes: PropTypes.object.isRequired,
};
export default compose(
graphql(LOGIN_MUTATION, { name: 'loginMutation' }),
withStyles(styles),
)(Login)

Drawer not opening

Good evening. I have a problem that I think is simple to solve but I could not get it because I was just a beginner in react. The problem is that the drawer that I put in my appbar just does not open, and there is no error on the console about it, so I would like the help of you guys.
PS: sorry for the bad English, I'm Brazilian.
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from 'material-ui/styles';
import Drawer from 'material-ui/Drawer';
import AppBar from 'material-ui/AppBar';
import Button from 'material-ui/Button';
import IconButton from 'material-ui/IconButton';
import Toolbar from 'material-ui/Toolbar';
import MenuIcon from 'material-ui-icons/Menu';
import TextField from 'material-ui/TextField';
import Paper from 'material-ui/Paper';
import Grid from 'material-ui/Grid';
import '../assets/scss/main.scss';
import img from '../assets/images/react.png';
const styles = theme => ({
root: {
width: '100%',
},
flex: {
flex: 1,
},
menuButton: {
marginLeft: -12,
marginRight: 20,
},
inputProps: {
step: 300,
},
button: {
margin: theme.spacing.unit,
},
input: {
display: 'none',
},
paper: {
padding: 50,
textAlign: 'center',
border: '5px solid black',
width: '100%',
},
paper1: {
backgroundColor: 'red',
marginTop: '13%',
},
img: {
width: '45%',
},
appbar: {
marginLeft: '-20.20%',
marginTop: '-20%',
width: '139.99%',
},
});
function ButtonAppBar(props) {
const { classes } = props;
const handleSubmit = (event) => {
event.preventDefault();
const data = {
email: document.getElementById('email').value,
password: document.getElementById('password').value,
};
console.log(data);
};
return (
<div className={styles.root}>
<Grid container spacing={8} alignItems="center" justify="center">
<Paper className={classes.paper}>
<div>
<AppBar position="static" className={classes.appbar}>
<Drawer />
<Toolbar>
<IconButton className={classes.menuButton} color="contrast" aria-label="Menu">
<MenuIcon />
</IconButton>
</Toolbar>
</AppBar>
</div>
<img src={img} alt="React" className={classes.img} /><br />
<form onSubmit={handleSubmit} noValidate>
<TextField id="email" type="email" label="Usuário" className={classes.user} /><br />
<TextField id="password" type="password" label="Senha" className={classes.senha} />
<div>
<AppBar position="static" className={classes.paper1} >
<Button type="submit" color="contrast">Login</Button>
</AppBar>
</div>
</form>
</Paper>
</Grid>
</div>
);
}
ButtonAppBar.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(ButtonAppBar);
Take a look at the Drawer demos in the documentation. You’ll see that the Drawer uses an open prop to specify whether it is open or not. In the demos, this is controlled my state.
The way this is usually handled is by using a button, like IconButton, in the AppBar with an onClick handler that issues a state change, resulting in a re-render.
The demos should help you reconfigure your app and get rolling. The most straightforward example of using component state to open and close the Drawer is the mobile portion of the Responsive Drawer demo.
It initializes state to false and renders the open prop using this.state.mobileOpen. The AppBar has an IconButton with handleDrawerToggle as it’s onClick handler, which changes state, causing the component to re-render.

Resources