Я пытался разработать страницу входа в систему с Django рамкой отдыха в качестве бэкэнда. Бэкэнд работает отлично, хотя я даже не могу настроить реакцию js. Я получаю сообщение об ошибке в файле Index. js реакции. Он сообщает «Неверный вызов ловушки. Хуки могут быть вызваны только внутри тела компонента функции»
Это ошибка, которую я получаю
Приложение. js
import React from 'react';
import './App.css';
import Paperbase from './Layout/Paperbase'
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import Login from './Layout/Login/Login'
import Register from './Layout/Register/Register'
export function App() {
return (
<BrowserRouter>
<Switch>
<Route path="/dashboard" render={() => <Paperbase /> } />
<Route path="/account/login" render={() =><Login />} />
<Route path="/account/register" render={() => <Register />} />
</Switch>
</BrowserRouter>
)
}
export default App
Указатель. js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import store from './store';
import { Provider } from 'react-redux';
import { render } from 'react-dom';
ReactDOM.render(
(<Provider store={store}>
<App/>
</Provider>),
document.getElementById('root') || document.createElement('div') // for testing purposes
);
serviceWorker.unregister();
Вход. js
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 Grid from '@material-ui/core/Grid';
import LockOutlinedIcon from '@material-ui/icons/LockOutlined';
import Typography from '@material-ui/core/Typography';
import Container from '@material-ui/core/Container';
import { withStyles } from '@material-ui/core/styles';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { login } from '../../actions/auth';
const styles = theme => ({
'@global': {
body: {
backgroundColor: theme.palette.common.white,
},
},
paper: {
marginTop: theme.spacing(25),
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
},
avatar: {
margin: theme.spacing(1),
backgroundColor: theme.palette.primary.light,
},
form: {
width: '100%', // Fix IE 11 issue.
marginTop: theme.spacing(1),
},
submit: {
margin: theme.spacing(3, 0, 2),
backgroundColor: theme.palette.primary.light,
},
});
class SignIn extends React.Component {
state = {
email: '',
password: '',
};
static propTypes = {
login: PropTypes.func.isRequired,
isAuthenticated: PropTypes.bool,
};
onSubmit = (e) => {
e.preventDefault();
this.props.login(this.state.email, this.state.password);
};
onChange = (e) => this.setState({ [e.target.name]: e.target.value });
render() {
const { classes } = this.props;
const { email, password } = this.state;
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} onSubmit={this.onSubmit}>
<TextField
variant="outlined"
margin="normal"
required
fullWidth
id="email"
label="Email Address"
name="email"
autoComplete="email"
autoFocus
onChange={this.onChange}
value={email}
/>
<TextField
variant="outlined"
margin="normal"
required
fullWidth
name="password"
label="Password"
type="password"
id="password"
autoComplete="current-password"
onChange={this.onChange}
value={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>
</form>
</div>
</Container>
);
}
}
const mapStateToProps = (state) => ({
isAuthenticated: state.auth.isAuthenticated,
});
export default (withStyles(styles)(SignIn));
authreducer. js
import {
USER_LOADED,
USER_LOADING,
AUTH_ERROR,
LOGIN_SUCCESS,
LOGIN_FAIL,
LOGOUT_SUCCESS,
REGISTER_SUCCESS,
REGISTER_FAIL,
} from '../actions/types';
const initialState = {
token: localStorage.getItem('token'),
isAuthenticated: null,
isLoading: false,
user: null,
};
export default function (state = initialState, action) {
switch (action.type) {
case USER_LOADING:
return {
...state,
isLoading: true,
};
case USER_LOADED:
return {
...state,
isAuthenticated: true,
isLoading: false,
user: action.payload,
};
case LOGIN_SUCCESS:
case REGISTER_SUCCESS:
localStorage.setItem('token', action.payload.token);
return {
...state,
...action.payload,
isAuthenticated: true,
isLoading: false,
};
case AUTH_ERROR:
case LOGIN_FAIL:
case LOGOUT_SUCCESS:
case REGISTER_FAIL:
localStorage.removeItem('token');
return {
...state,
token: null,
user: null,
isAuthenticated: false,
isLoading: false,
};
default:
return state;
}
}
авторизаций. js
import axios from 'axios';
import {
USER_LOADED,
USER_LOADING,
LOGIN_SUCCESS,
LOGOUT_SUCCESS,
REGISTER_SUCCESS,
} from './types';
// CHECK TOKEN & LOAD USER
export const loadUser = () => (dispatch, getState) => {
// User Loading
dispatch({ type: USER_LOADING });
axios
.get('http://localhost:8000/api/auth/user', tokenConfig(getState))
.then((res) => {
dispatch({
type: USER_LOADED,
payload: res.data,
});
})
.catch((err) => {
console.log(err)
});
};
// LOGIN USER
export const login = (email, password) => (dispatch) => {
// Headers
const config = {
headers: {
'Content-Type': 'application/json',
},
};
const body = JSON.stringify({ email, password });
axios
.post('http://localhost:8000/api/auth/login', body, config)
.then((res) => {
dispatch({
type: LOGIN_SUCCESS,
payload: res.data,
});
})
.catch((err) => {
console.log(err.response.data)
});
};
// REGISTER USER
export const register = ({ username, password, email }) => (dispatch) => {
// Headers
const config = {
headers: {
'Content-Type': 'application/json',
},
};
// Request Body
const body = JSON.stringify({ username, email, password });
axios
.post('http://localhost:8000/api/auth/register', body, config)
.then((res) => {
dispatch({
type: REGISTER_SUCCESS,
payload: res.data,
});
})
.catch((err) => {
console.log(err.response.data)
});
};
// LOGOUT USER
export const logout = () => (dispatch, getState) => {
axios
.post('http://localhost:8000/api/auth/logout/', null, tokenConfig(getState))
.then((res) => {
dispatch({ type: 'CLEAR_LEADS' });
dispatch({
type: LOGOUT_SUCCESS,
});
})
.catch((err) => {
console.log(err.response.data)
});
};
// Setup config with token - helper function
export const tokenConfig = (getState) => {
// Get token from state
const token = getState().auth.token;
// Headers
const config = {
headers: {
'Content-Type': 'application/json',
},
};
// If token, add to headers config
if (token) {
config.headers['Authorization'] = `Token ${token}`;
}
return config;
};