【问题标题】:TypeError: Cannot read property 'profile' of undefinedTypeError:无法读取未定义的属性“配置文件”
【发布时间】:2019-02-20 22:03:24
【问题描述】:

我刚开始学习 Redux,我遇到了这个错误,似乎无法弄清楚我哪里出错了。在我的 profileReducer.js 文件中,我设置了一个 initialState 以使 profile 等于 null。在某个地方,有些事情失败了,如果我 console.log(this.state) 配置文件未定义。

错误:

TypeError: Cannot read property 'profile' of undefined
Dashboard.render
src/components/dashboard/Dashboard.js:11
   8 |   this.props.getCurrentProfile();
   9 | }
  10 | 
> 11 | render() {
  12 |   const { user } = this.props.auth;
  13 |   const { profile, loading } = this.props.profile;
  14 | 

profileReducer.js

import {
  GET_PROFILE,
  PROFILE_LOADING,
  CLEAR_CURRENT_PROFILE
} from "../actions/types";

const initialState = {
  profile: null,
  profiles: null,
  loading: false
};

export default function(state = initialState, action) {
  switch (action.type) {
    case PROFILE_LOADING:
      return {
        ...state,
        loading: true
      };
    case GET_PROFILE:
      return {
        ...state,
        profile: action.payload,
        loading: false
      };
    case CLEAR_CURRENT_PROFILE:
      return {
        ...state,
        profile: null
      };
    default:
      return state;
  }
}

profileActions.js

import axios from "axios";

import {
  GET_PROFILE,
  PROFILE_LOADING,
  CLEAR_CURRENT_PROFILE,
  GET_ERRORS
} from "./types";

// Get current profile
export const getCurrentProfile = () => dispatch => {
  dispatch(setProfileLoading());
  axios
    .get("/api/profile")
    .then(res =>
      dispatch({
        type: GET_PROFILE,
        payload: res.data
      })
    )
    .catch(err =>
      dispatch({
        type: GET_PROFILE,
        payload: {}
      })
    );
};

// Create Profile
export const createProfile = (profileData, history) => dispatch => {
  axios
    .post("/api/profile", profileData)
    .then(res => history.push("/dashboard"))
    .catch(err =>
      dispatch({
        type: GET_ERRORS,
        payload: err.response.data
      })
    );
};

// Profile loading
export const setProfileLoading = () => {
  return {
    type: PROFILE_LOADING
  };
};

// Clear profile
export const clearCurrentProfile = () => {
  return {
    type: CLEAR_CURRENT_PROFILE
  };
};

仪表板.js

import React, { Component } from "react";
import PropTypes from "prop-types";
import { connect } from "react-redux";
import { getCurrentProfile } from "../../actions/profileActions";

class Dashboard extends Component {
  componentDidMount() {
    this.props.getCurrentProfile();
  }

  render() {
    const { user } = this.props.auth;
    const { profile, loading } = this.props.profile;

    let dashboardContent;

    if (profile === null || loading) {
      dashboardContent = <h4>Loading</h4>;
    } else {
      dashboardContent = <h1>Hello</h1>;
    }

    return (
      <div className="dashboard">
        <div className="container">
          <div className="row">
            <div className="col-md-12">
              <h1 className="display-4">Dashboard</h1>
              {dashboardContent}
            </div>
          </div>
        </div>
      </div>
    );
  }
}

Dashboard.propTypes = {
  getCurrentProfile: PropTypes.func.isRequired,
  auth: PropTypes.object.isRequired,
  profile: PropTypes.object.isRequired
};

const mapStateToProps = state => ({
  profile: state.profile,
  auth: state.auth
});

export default connect(
  mapStateToProps,
  { getCurrentProfile }
)(Dashboard);

App.js

import React, { Component } from "react";
import "./App.css";
import Navbar from "./components/layout/Navbar";
import Footer from "./components/layout/Footer";
import Landing from "./components/layout/Landing";
import Login from "./components/auth/Login";
import Register from "./components/auth/Register";
import { BrowserRouter as Router, Route } from "react-router-dom";
import jwt_decode from "jwt-decode";
import setAuthToken from "./utils/setAuthToken";
import { setCurrentUser, logoutUser } from "./actions/authActions";
import { clearCurrentProfile } from "./actions/profileActions";
import { Provider } from "react-redux";
import store from "./store";
import Dashboard from "./components/dashboard/Dashboard";

// Check for token
if (localStorage.jwtToken) {
  // Set auth token header auth
  setAuthToken(localStorage.jwtToken);
  // Decode token and get user info and exp
  const decoded = jwt_decode(localStorage.jwtToken);
  // Set user and isAuthenticated
  store.dispatch(setCurrentUser(decoded));
  // Check for expired token
  const currentTime = Date.now() / 1000;
  if (decoded.exp < currentTime) {
    // Logout user
    store.dispatch(logoutUser());
    // clear current profile
    store.dispatch(clearCurrentProfile());

    // Redirect to login
    window.location.href = "/login";
  }
}

class App extends Component {
  render() {
    return (
      <Provider store={store}>
        <Router>
          <div className="App">
            <Navbar />
            <Route exact path="/" component={Landing} />
            <div className="container">
              <Route exact path="/register" component={Register} />
              <Route exact path="/login" component={Login} />
              <Route exact path="/dashboard" component={Dashboard} />
            </div>
            <Footer />
          </div>
        </Router>
      </Provider>
    );
  }
}

export default App;

store.js

import { createStore, applyMiddleware, compose } from "redux";
import thunk from "redux-thunk";
import rootReducer from "./reducers";

const initialState = {};

const middleware = [thunk];

const store = createStore(
  rootReducer,
  initialState,
  compose(
    applyMiddleware(...middleware),
    window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
  )
);

export default store;

【问题讨论】:

  • 大量代码,我们在这里很难提供帮助。你能在profileActions.jsgetCurrentProfile...then() 块内console.log(res.data) 吗?您的前端是否成功从后端检索配置文件?
  • @JacobMoore,你如何组合你的减速器?当您收到此错误时,没有profile 状态。所以,要么这里发生了奇怪的事情,要么州名不知何故弄乱了。
  • @JacobMoore,尽管我讨厌你添加 more 代码,但我认为你需要发布 ./store 来回答 @devserkan '问题
  • storeindex.js 可能在 reducers 目录中,如果他像我一样使用他的减速器:)
  • 我编辑了帖子并包含了商店。当我在 then 块中使用 console.log(res.data) 或在 catch 块中使用 console.log(err) 时,没有任何记录。

标签: reactjs redux react-redux


【解决方案1】:

index.js

export default combineReducers({
  auth: authReducer,
  errors: errorReducer,
  profie: profileReducer
});

几个小时后.....profie 应该是 profile =)

【讨论】:

  • 这就是我想要组合减速器部分的原因 :) 很高兴你解决了它。实际上,我认为在这里打错字是一个常见的错误:)
猜你喜欢
  • 2022-07-06
  • 2022-07-12
  • 2018-06-03
  • 2022-01-05
  • 2022-01-01
  • 1970-01-01
  • 2021-04-17
  • 2016-05-12
  • 1970-01-01
相关资源
最近更新 更多