TypeError: Невозможно прочитать свойство 'auth' с нулевым значением reactjs с избыточным значением - PullRequest
0 голосов
/ 04 мая 2020

Я получаю эту ошибку в своем коде. TypeError: не могу прочитать свойство 'auth' со значением null. Я создал два типа навигационной ссылки в моем проекте privateLink и publicLink. Я хочу, чтобы личная ссылка отображалась при входе пользователя в систему. Эта ошибка появляется. Пожалуйста, помогите мне.

При написании этого кода в заголовке. js file const {isAuthenticated} = this.state.auth; Эта ошибка появляется. Ошибка: Не удается прочитать свойство 'auth' с нулевым

index. js файл редуктора комбайна

import { combineReducers } from "redux";
import authReducer from './AuthReducer';
import errorReducer from './ErrorReducer';


export default combineReducers({
    auth: authReducer,
    error: errorReducer
})

Header. js file

import React, { Component, Fragment } from 'react'
import { Link } from 'react-router-dom'
import { Navbar, Nav } from 'react-bootstrap'
import { connect } from 'react-redux';
import { logout } from '../actions/authAction';
import PropTypes from 'prop-types'

export class Header extends Component {

  static propTypes = {
    auth: PropTypes.object.isRequired,
    logout: PropTypes.func.isRequired
  };

  render() {

    const {isAuthenticated} = this.state.auth;


    const privateLink = (
      <Fragment>
        <span className="navbar-text">
          {/* <strong>{user ? `Welcome ${user.name}` : null}</strong> */}
        </span>
        <Link className="nav-link active" to="/Profile">Profile<span className="sr-only">(current)</span></Link>
        <Link className="nav-link active" to="#" onClick={this.props.logout} >Logout<span className="sr-only">(current)</span></Link>
      </Fragment>
    )
    const publicLink = (
      <Fragment>
        <Link className="nav-link active" to="/">Home<span className="sr-only">(current)</span></Link>
        <Link className="nav-link active" to="/About">About<span className="sr-only">(current)</span></Link>
        <Link className="nav-link active" to="/Register">Register<span className="sr-only">(current)</span></Link>
        <Link className="nav-link active" to="/Login">Login<span className="sr-only">(current)</span></Link>
      </Fragment>
    )
    return (
      <Fragment>
        <div className="shadow sticky-top" >
          <Navbar className="navbar-dark bg-danger" expand="lg">
            <Nav>
              <Link className="nav-link active" to="/">Domestic India</Link>
            </Nav>
            <Navbar.Toggle aria-controls="basic-navbar-nav" />
            <Navbar.Collapse id="basic-navbar-nav">
              <Nav className="ml-auto">
                {publicLink} {privateLink}
                {/* {isAuthenticated ? privateLink : publicLink} */}
              </Nav>
            </Navbar.Collapse>
          </Navbar>
        </div>
      </Fragment>
    )
  }
}

const MapStateToProps = state => ({
  auth: state.auth
});

export default connect(MapStateToProps, { logout }, null)(Header);

Файл authAction. js

import axios from 'axios';
import { returnErrors } from './errorAction'
import {
    USER_LOADING,
    USER_LOADED,
    AUTH_ERROR,
    REGISTER_FAIL,
    REGISTER_SUCCESS,
    LOGIN_FAIL,
    LOGIN_SUCCESS,
    LOGOUT_SUCCESS,
} from './Types';

// Check Token & load user
export const loadUser = () => (dispatch, getState) => {
    // User loading
    dispatch({ type: USER_LOADING });

    axios.get('/api/user', tokenConfig(getState))
        .then(res => dispatch({
            type: USER_LOADED,
            payload: res.data
        }))
        .catch(error => {
            dispatch(returnErrors(error.response.data, error.response.status));
            dispatch({
                type: AUTH_ERROR
            })
        })

}



// Register User
export const register = ({ name, email, password, mobile, address, city, state, zipCode }) => async dispatch => {
    // Headers
    const config = {
        headers: {
            "Content-type": "application/json"
        }
    }

    // Request Body
    const body = JSON.stringify({ name, email, password, mobile, address, city, state, zipCode });


    try {
        const res = await axios.post('/api/users', body, config)
        dispatch({
            type: REGISTER_SUCCESS,
            payload: res.data
        })
    } catch (error) {
        if (error) {
            dispatch(returnErrors(error.response.data.msg, error.response.status, 'REGISTER_FAIL'));
        }
        dispatch({
            type: REGISTER_FAIL
        });
    }
}

// Login User
export const login = ({ email, password }) => async dispatch => {
    // Headers
    const config = {
        headers: {
            "Content-type": "application/json"
        }
    }

    // Request Body
    const body = JSON.stringify({ email, password });


    try {
        const res = await axios.post('/api/login', body, config)
        dispatch({
            type: LOGIN_SUCCESS,
            payload: res.data
        })
    } catch (error) {
        if (error) {
            dispatch(returnErrors(error.response.data.msg, error.response.status, 'LOGIN_FAIL'));
        }
        dispatch({
            type: LOGIN_FAIL
        });
    }
}

// Logout user
export const logout = () => {
    return {
        type: LOGOUT_SUCCESS
    }
}

// Setup config/header and token

export const tokenConfig = getState => {
    // Get token from localStorage
    const token = getState().auth.token;
    // Headers
    const config = {
        headers: {
            "Content-type": "application/json"
        }
    };

    if (token) {
        config.headers['x-auth-token'] = token;
    }
    return config;
}

Файл errorAction. js

   import { GET_ERRORS, CLEAR_ERRORS } from './Types';

// Return Errors
export const returnErrors = (msg, status, id = null) => {
    return {
        type: GET_ERRORS,
        payload: { msg, status, id}
    }
};

// Clear Errors
export const clearErrors = () => {
    return {
        type: CLEAR_ERRORS,
    }
}

Файл AuthReducer. js

import {
    USER_LOADING,
    USER_LOADED,
    AUTH_ERROR,
    REGISTER_SUCCESS,
    REGISTER_FAIL,
    LOGIN_SUCCESS,
    LOGIN_FAIL,
    LOGOUT_SUCCESS,

} from '../actions/Types'

const initialState = {
    token: localStorage.getItem('token'),
    isAuthenticated: false,
    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 REGISTER_SUCCESS:
        case LOGIN_SUCCESS:
            localStorage.setItem('token', action.payload.token)
            return {
                ...state,
                ...action.payload,
                isAuthenticated: true,
                isLoading: false
            };
        case AUTH_ERROR:
        case REGISTER_FAIL:
        case LOGIN_FAIL:
        case LOGOUT_SUCCESS:
            localStorage.removeItem('token');
            return {
                ...state,
                token: null,
                user: null,
                isAuthenticated: false,
                isLoading: false
            };
        default:
            return state;
    }
}

1 Ответ

0 голосов
/ 04 мая 2020

Проблема в том, что вы пытаетесь получить auth из состояния компонента, но вы должны прочитать props в render().

Заменить const {isAuthenticated} = this.state.auth; на const {isAuthenticated} = this.props.auth;.

...