在React中将类组件更改为功能组件

时间:2020-03-10 05:25:09

标签: reactjs

我有这段代码,并试图将其转换为功能组件,但遇到了麻烦。我在return()部分中有一个表单,可以将值传递给状态,然后传递给props?据我了解,通过mapStateToProps ...但是,切换到function()组件后,我迷失了在这里要做的事情。

       class Login extends Component {
          state = {
            login: '',
            password: '',
            keepLogged: false
          };

          changeValue = event => {
            event.preventDefault();
            const value = event.target.value;
            const name = event.target.name;

            this.setState({
              [name]: value
            });
          };

          loginUser = () => {
            const { login, password } = this.state;
            const { requestSignIn } = this.props;

            requestSignIn({ login, password });
          };

          render() {
            const { login, password } = this.state;
       return (
     <LoginWrapper>
    <Container style={{ border: '1px solid #757575', padding: '5%' }}>
      <Row>
        <Col style={{ textAlign: 'right', marginRight: '25px' }}>
        </Col>
      </Row>
      <Row>
        <Col>
          <LoginHeader>Log In to Your Account</LoginHeader>
        </Col>
      </Row>
      <Row>
        <Col>
          <LoginForm>
            <FormControl
              name='login'
              type='text'
              placeholder='Username/Email'
              value={login}
              onChange={this.changeValue}
              style={{ marginBottom: '10px' }}
            />
            <FormControl
              name='password'
              type='password'
              placeholder='Password'
              value={password}
              onChange={this.changeValue}
              style={{ marginBottom: '10px' }}
            />
            <Button
              variant='info'
              value='Log In'
              onClick={() => this.loginUser()}
            >
              Log In
            </Button>
          </LoginForm>
        </Col>
      </Row>
      <Row>
        <Col>
          <LoginBottom
            onClick={() => history.push('/registration')}
            style={{ marginTop: '30px' }}
          >
            Need an account?{' '}
            <Link style={{ color: '#007bff' }}>Sign Up</Link>
          </LoginBottom>
        </Col>
      </Row>
    </Container>
  </LoginWrapper>
)

const mapDispatchToProps = dispatch => ({
  requestSignIn: data => dispatch(requestSignIn(data))
});

export default connect(null, mapDispatchToProps)(Login);

到目前为止,我已经做到了。我被困在这里。试图为每个登录名,密码和keepLo​​gged引入useState,但失败:/

    function Login(props) {
      const [inputs, setInputs] = useState({
        // you can login with email or username
        login: '',
        password: '',
        keepLogged: false
      });

      const { login, password } = inputs;

      function handleChange(e) {
        e.preventDefault();
        const { name, value } = e.target;
        setInputs(inputs => ({ ...inputs, [name]: value }));
      }

      const loginUser = () => {
        const setInputs = inputs;
        const { requestSignIn } = props;

        requestSignIn({ setInputs });
      };

      return (
   <Grid container component='main' className={classes.root}>
  <CssBaseline />
  <Grid item xs={false} sm={4} md={7} className={classes.image} />
  <Grid item xs={12} sm={8} md={5} component={Paper} elevation={6} square>
    <div className={classes.paper}>
      <div>
        <img src={Logo} style={{ width: 300 }} />
      </div>
      <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'
          value={login}
          onChange={handleChange}
          name='login'
          autoComplete='email'
          autoFocus
        />
        <TextField
          variant='outlined'
          margin='normal'
          required
          fullWidth
          name='password'
          label='Password'
          value={password}
          onChange={handleChange}
          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'
          value='Log In'
          className={classes.submit}
          onClick={() => loginUser()}
        >
          Sign In ?
        </Button>
        <Grid container>
          <Grid item xs>
            <Link href='#' variant='body2'>
              Forgot password?
            </Link>
          </Grid>
          <Grid item>
            <Link
              variant='body2'
              onClick={() => history.push('/registration')}
            >
              {"Don't have an account? Sign Up"}
            </Link>
          </Grid>
        </Grid>
        <Box mt={5}>
          <Copyright />
        </Box>
      </form>
    </div>
  </Grid>
</Grid>

)

const mapDispatchToProps = dispatch => ({
  requestSignIn: data => dispatch(requestSignIn(data))
});

export default connect(null, mapDispatchToProps)(Login);

1 个答案:

答案 0 :(得分:0)

我认为您已经到了那里,只是清除一些冗余代码的情况。

      const [inputs, setInputs] = useState({
            login: '',
            password: '',
            keepLogged: false
      });

      const { login, password } = inputs;

      function handleChange(e) {
        e.preventDefault();
        const { name, value } = e.target;
        // Set the inputs object directly, no need to callback
        setInputs({ ...inputs, [name]: value });
      }

      const loginUser = () => {
        const { requestSignIn } = props;
        // Login and password are already initialised
        requestSignIn({login, password});
      };

您可能还希望将事件对象传递给处理程序,如下所示:

onChange={e => handleChange(e)}

相关问题