登录突变在material-ui中不能始终如一地工作。

时间:2018-10-03 12:31:11

标签: reactjs graphql material-ui

我正在尝试通过graphql突变使用material-ui在React中创建示例登录表单。但是登录表单无法正常工作。

我只能登录几次,但即使在那些时候,我也看不到控制台中通过loginMutation道具传递的任何数据。有人可以告诉我我在做什么错吗?

这是我要创建的登录组件

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)

1 个答案:

答案 0 :(得分:0)

由于Button标记,发生了错误。尽管它的类型为=“ submit”,但仍未提交表单,因此输入数据未出现在“ _confirm”中。我想知道为什么,我一定在这里错过了什么。

现在,我在Button内部创建了一个div标签,并在其中添加了onClick处理程序,而不是Button标签。

所以,编辑后的代码只有很小的变化

<Button color="primary" className = {classes.submit} variant="raised" fullWidth>
  <div className="test" onClick={() => this._confirm()} >
    Sign in
  </div>
</Button>

这是完整的源代码:

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)