Changing class component to functional component in React

徘徊边缘 提交于 2021-02-11 15:28:07

问题


I have this code and tried to convert it to functional component and I am stuck. I have a form in return() part that passes the value to the state and then to props? via mapStateToProps as far as I understand... But, switching to function() component, I am lost what I have to do here.

       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);

So far, I have done this. I am stuck here. Tried to introduce useState for each login, password, and keepLogged but failed :/

    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:


I think you were most of the way there, just a case of clearing up some redundant code.

      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});
      };

You may also want to pass the event object to the handler like so:

onChange={e => handleChange(e)}



来源:https://stackoverflow.com/questions/60611973/changing-class-component-to-functional-component-in-react

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!