类型错误:无法读取未定义的属性“路径名”

时间:2021-05-06 22:03:30

标签: reactjs redux react-redux

我正在网站上创建注册和登录,但出现此错误 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

0 个答案:

没有答案