#reactjs #typescript #react-redux #react-hooks
Вопрос:
У меня есть форма входа в систему, которая использует useState
hook для хранения состояния входных данных (имя пользователя и пароль), поэтому я могу передать эти данные функции, используя createAsyncThunk
эту запись в API, и сохранить ее результат.
В настоящее время вот что у меня есть:
Войдите в систему.tsx
import React, { useState } from 'react';
import {
Avatar,
Button,
Checkbox,
Container,
CssBaseline,
FormControlLabel,
Grid,
Link,
TextField,
Typography,
} from '@material-ui/core';
import LockOutlinedIcon from '@material-ui/icons/LockOutlined';
import { makeStyles } from '@material-ui/core/styles';
import { useAuth } from '../hooks';
import { useHistory } from 'react-router';
import { authManager } from '../authManager';
const useStyles = makeStyles((theme) => ({
//...
}));
const Login: React.FC = () => {
const classes = useStyles();
const { push } = useHistory();
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const handleUsername: React.ChangeEventHandler<HTMLInputElement> = (e) =>
setUsername(e.target.value);
const handlePassword: React.ChangeEventHandler<HTMLInputElement> = (e) =>
setPassword(e.target.value);
const SignIn = async () => {
await useAuth(username, password);
};
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="E-mail"
name="email"
autoComplete="email"
value={username}
onChange={handleUsername}
autoFocus
/>
<TextField
variant="outlined"
margin="normal"
required
fullWidth
name="password"
label="Senha"
type="password"
id="password"
autoComplete="current-password"
value={password}
onChange={handlePassword}
/>
<Button
fullWidth
variant="contained"
color="primary"
className={classes.submit}
onClick={SignIn}
>
Sign In
</Button>
</form>
</div>
</Container>
);
};
export default Login;
useAuth.ts (пользовательский крючок)
import React, { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { authOperations } from 'src/features/auth/redux/';
import { getAuth } from 'src/features/auth/redux/authSelector';
export default (username: string, password: string) => {
const dispatch = useDispatch();
const auth = useSelector(getAuth);
useEffect(() => {
dispatch(
authOperations.getAccessToken({
username,
password,
})
);
}, [dispatch, username, password]);
return {
auth,
};
};
Это не работает, на самом деле я получаю Invalid hook call. Hooks can only be called inside of the body of a function component.
ошибку.
Итак, как я запускаю пользовательский метод крючка с помощью нажатия кнопки?
Ответ №1:
Я думаю, что когда вы вызовете useAuth, он вернет функцию, которую вы хотите вызвать позже.
Например, после
const [password, setPassword] = useState('');
вы можете положить
const [password, setPassword] = useState('');
const auth = useAuth();
Затем вы можете вызвать auth() в функции входа, вместо того, чтобы вызывать useAuth там.
Возможно, после этого вам придется исправить еще несколько вещей, но это должно вывести вас на правильный путь.