我正在网站上创建注册和登录,但出现此错误 TypeError: Cannot read property 'pathname' of undefined
我不知道此错误来自何处。我是 redux
新手,所以如果有人知道我为什么会收到此错误,请向我解释,以便下次我会知道我是否仍然会收到此错误。
谢谢
这是我的代码
Index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { Provider } from 'react-redux';
import { BrowserRouter as Router } from 'react-router-dom';
import 'bootstrap/dist/css/bootstrap.min.css';
import store from './Store';
window.store = store;
ReactDOM.render(
<Provider store= {store}>
<Router>
<React.StrictMode>
<App />
</React.StrictMode>
</Router>
</Provider>,
document.getElementById('root')
);
reportWebVitals();
app.js
import './App.css';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import HomePage from './Home_Search_Client/Containers/HomePage';
import About from './Home_Search_Client/Containers/About';
import Feedback from './Home_Search_Client/Containers/Feedback';
import Signup from './Home_Search_Client/Containers/Signup';
import Signin from './Home_Search_Client/Containers/Signin';
import PrivateRoute from './Home_Search_Client/Components/HOC/PrivateRoute';
import { useDispatch, useSelector } from 'react-redux';
import { useEffect } from 'react';
import { isUserLoggedIn } from './Home_Search_Client/actions';
function App() {
const dispatch = useDispatch();
const auth = useSelector((state) => state.auth);
useEffect(() => {
if(!auth.authenticate){
dispatch(isUserLoggedIn)
}
}, [auth.authenticate]);
return (
<Router>
<Switch>
<PrivateRoute path='/' exact component={HomePage} />
<PrivateRoute path='/about' component={About} />
<PrivateRoute path='/feedback' component={Feedback} />
<Route path='/signup' component={Signup} />
<Route path='/signin' component={Signin} />
</Switch>
</Router>
);
}
export default App;
存储(index.js)
import { createStore, applyMiddleware } from 'redux';
import { composeWithDevTools } from 'redux-devtools-extension';
import rootReducer from '../Home_Search_Client/reducers';
import thunk from 'redux-thunk';
const store = createStore(rootReducer, composeWithDevTools(
applyMiddleware(thunk)
));
export default store;
auth.actinons.js
import axios from '../helpers/axios';
import { authConstants } from './constants';
export const signin = (user) => {
return async (dispatch) => {
dispatch({ type: authConstants.LOGIN_REQUEST });
const res = await axios.post(`/signin`, {
...user
});
if (res.status === 200) {
const { token, user } = res.data;
localStorage.setItem('token', token);
localStorage.setItem('user', JSON.stringify(user));
dispatch({
type: authConstants.LOGIN_SUCCESS,
payload: {
token, user
}
});
} else {
if (res.status === 400) {
dispatch({
type: authConstants.LOGIN_FAILURE,
payload: { error: res.data.error }
});
}
}
}
}
export const isUserLoggedIn = () => {
return async dispatch => {
const token = localStorage.getItem('token');
if (token) {
const user = JSON.parse(localStorage.getItem('user'));
dispatch({
type: authConstants.LOGIN_SUCCESS,
payload: {
token, user
}
});
}else{
dispatch({
type: authConstants.LOGIN_FAILURE,
payload: { error: 'Failed to login' }
});
}
}
}
export const signout = () => {
return async dispatch => {
dispatch({ type: authConstants.LOGOUT_REQUEST });
const res = await axios.post(`/signout`);
if (res.status === 200) {
localStorage.clear();
dispatch({ type: authConstants.LOGOUT_SUCCESS });
} else {
dispatch({
type: authConstants.LOGOUT_FAILURE,
payload: { error: res.data.error }
});
}
}
}
user.action.js
import axios from '../helpers/axios';
import { userContants } from './constants';
export const signup = (user) => {
return async (dispatch) => {
dispatch({ type: userContants.USER_REGISTER_REQUEST });
const res = await axios.post(`/signup`, {
...user
});
if (res.status === 201) {
const { message } = res.data;
dispatch({
type: userContants.USER_REGISTER_SUCCESS,
payload: { message }
});
} else {
if (res.status === 400) {
dispatch({
type: userContants.USER_REGISTER_FAILURE,
payload: { error: res.data.error }
});
}
}
}
};
Signup.js(容器)
import React, { useEffect, useState } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { Button, Col, Container, Form, Row } from 'react-bootstrap'
import Layout from '../../Components/Layout'
import Input from '../../Components/UI/Input'
import { signup } from '../../actions'
import { Redirect } from 'react-router'
const Signup = (props) => {
const [firstName, setFirstName] = useState('');
const [lastName, setLastName] = useState('');
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const auth = useSelector((state) => state.auth)
const user = useSelector((state) => state.user)
const dispatch = useDispatch();
useEffect(() => {
if(!user.loading){
setFirstName('');
setLastName('');
setEmail('');
setPassword('');
}
}, [user.loading]);
const userSignup = (e) => {
e.preventDefault();
const user = {
firstName,
lastName,
email,
password
};
dispatch(signup(user));
};
if(auth.authenticate) {
return <Redirect to={'/'} />
}
if(user.loading) {
return <p>Loading...</p>
}
return (
<Layout>
<Container>
{user.message}
<Row>
<Col md={{ span:6, offset:3 }}>
<Form onSubmit={userSignup}>
<Row>
<Col md = {6}>
<Input
label = 'First Name'
placeholder='First Name'
value= {firstName}
type='text'
onChange={(e) => setFirstName(e.target.value)}
/>
</Col>
<Col md = {6}>
<Input
label = 'Last Name'
placeholder='Last Name'
value= {lastName}
type='text'
onChange={(e) => setLastName(e.target.value)}
/>
</Col>
</Row>
<Input
label='Email'
placeholder='Email'
value={email}
type='email'
onChange={(e) => setEmail(e.target.value)}
/>
<Input
label='Password'
placeholder='Password'
value={password}
type='password'
onChange={(e) => setPassword(e.target.value)}
/>
<Button variant='primary' type='submit' >
Submit
</Button>
</Form>
</Col>
</Row>
</Container>
</Layout>
)
}
export default Signup
Signin.js(容器)
import React, { useState } from 'react'
import { Button, Col, Container, Form, Row } from 'react-bootstrap'
import Layout from '../../Components/Layout';
import Input from '../../Components/UI/Input';
import { useDispatch, useSelector } from 'react-redux';
import { signin } from '../../actions'
import { Redirect } from 'react-router';
const Signin = () => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const auth = useSelector(state => state.auth);
const dispatch = useDispatch();
const userLogin = (e) => {
e.preventDefault();
const user = {
email, password
}
dispatch(signin(user))
}
if(auth.authenticate) {
return <Redirect to={'/'} />
}
return (
<Layout>
<Container>
<Row>
<Col md={{ span: 6, offset: 3 }}>
<Form onSubmit={userLogin}>
<Input
label='Email'
placeholder='Email'
value={email}
type='email'
onChange={(e) => setEmail(e.target.value)}
/>
<Input
label='Password'
placeholder='Password'
value={password}
type='password'
onChange={(e) => setPassword(e.target.value)}
/>
<Button variant='primary' type='submit'>
Submit
</Button>
</Form>
</Col>
</Row>
</Container>
</Layout>
)
}
export default Sign in
axios.js(助手)
import axios from 'axios';
import { api } from '../../urlConfig';
import store from '../../Store';
import { authConstants } from '../actions/constants';
const token = window.localStorage.getItem('token');
const axiosInstance = axios.create({
baseURL: api,
headers:{
'Authorization': token ? `${token}` : ''
}
});
axiosInstance.interceptors.request.use((req) => {
const { auth } = store.getState();
if(auth.token){
req.headers.Authorization = `${auth.token}`
}
return req;
});
axiosInstance.interceptors.response.use((res) => {
return res;
}, (error) => {
console.log(error.response);
const status = error.response ? error.response.status : 500;
if(status && status === 500) {
localStorage.clear();
store.dispatch({ type: authConstants.LOGOUT_SUCCESS });
}
return Promise.reject(error);
})
export default axiosInstance;
PrivateRoute.js
import React from 'react'
import { Redirect, Route } from 'react-router'
const PrivateRoute = ({ component: Component, ...rest }) => {
return <Route {...rest} component={(props) => {
const token = window.localStorage.getItem('token');
if(token) {
return <Component {...props} />
}else{
return <Redirect to={'signin'} />
}
}} />
}
export default PrivateRoute;
Header.js
import React from 'react';
import Logo from '../../../Logos/main-logo.png';
import { Navbar, Button, Nav } from 'react-bootstrap';
import { NavLink } from 'react-router-dom';
import KeyboardReturnOutlinedIcon from '@material-ui/icons/KeyboardReturnOutlined';
import './style.css';
import { useDispatch, useSelector } from 'react-redux';
import { signout } from '../../actions';
const Header = () => {
const auth = useSelector((state) => state.auth);
const dispatch = useDispatch();
const logout = () => {
dispatch(signout());
}
const renderLoggedInLinks = () => {
return (
<Nav className='host_btn ml-auto'>
<Nav.Link><NavLink className='NavLink' to={`/`}>Home</NavLink></Nav.Link>
<Nav.Link><NavLink className='NavLink ml-2' to={`/about`}>About</NavLink></Nav.Link>
<Nav.Link><NavLink className='NavLink ml-2' to={`/feedback`}>Feedback</NavLink></Nav.Link>
<Nav.Link><NavLink className='NavLink ml-2' onClick={logout}>Signout</NavLink></Nav.Link>
<Button className='ml-5'>Become a host <KeyboardReturnOutlinedIcon /> </Button>
</Nav>
);
};
const renderNonLoggedInLinks = () => {
return (
<Nav className='host_btn ml-auto'>
<Nav.Link><NavLink className='NavLink' to={`/`}>Home</NavLink></Nav.Link>
<Nav.Link><NavLink className='NavLink ml-2' to={`/about`}>About</NavLink></Nav.Link>
<Nav.Link><NavLink className='NavLink ml-2' to={`/feedback`}>Feedback</NavLink></Nav.Link>
<Nav.Link><NavLink className='NavLink ml-2' to={`/signup`}>Signup</NavLink></Nav.Link>
<Nav.Link><NavLink className='NavLink ml-2' to={`/signin`}>Signin</NavLink></Nav.Link>
<Button className='ml-5'>Become a host <KeyboardReturnOutlinedIcon /> </Button>
</Nav>
)
}
return (
<Navbar className='mt-2 ml-2 mr-2' collapseOnSelect expand='sm' bg='light' variant='light'>
<Navbar.Toggle aria-controls='responsive-navbar-nav' />
<Navbar.Collapse id='responsive-navbar-nav' >
<Navbar.Brand className='logo-img' to="#home"><img src={Logo} /></Navbar.Brand>
<Nav className='host_btn ml-auto'>
{auth.authenticate ? renderLoggedInLinks() : renderNonLoggedInLinks()}
</Nav>
</Navbar.Collapse>
</Navbar>
)
}
export default Header