Есть несколько проблем с вашим кодом. Наиболее очевидным является то, как вы проверяете profile
:
if (profile === null || loading)
Мне кажется, что profile
устанавливается как undefined
, а loading
устанавливается как false
, и, следовательно, он передает оператор if
.
Вместо этого сначала установите profile
как пустой объект {}
. Затем вы можете использовать функцию lodash isEmpty()
, чтобы проверить, все ли еще пусто. Это также сохранит вашу propTypes
проверку как 1: 1. Если это объект, он остается объектом. Если это строка, она остается строкой и так далее. Снова держите это 1: 1.
Кроме того, при проверке типа реквизита опишите shape
из object
. Когда-нибудь в будущем вам больше всего понравится использовать eslint
, и он выдаст ошибки об использовании общих дескрипторов, таких как Proptypes.array
и Proptypes.object
. Хотя это может показаться излишним, оно может выделить ошибки в вашем объекте, если свойство отличается от описанной формы.
Рабочие коды и коробка :
Этот пример включает в себя некоторое использование расширенного / промежуточного кода, поэтому я думаю, что некоторые из них не будут иметь смысла. Если у вас есть вопросы, не стесняйтесь спрашивать.
Используется в этом примере кода: Определение структуры объекта ES6 , Функции жирной стрелки с упрощенным возвратом , Свойства класса жирной стрелки , оператор распространения и троичный оператор .
Реорганизованная и упрощенная версия вашего кода ...
контейнеры / Dashboard
import isEmpty from "lodash/isEmpty";
import React, { PureComponent } from "react";
import PropTypes from "prop-types";
import { connect } from "react-redux";
import { getCurrentProfile } from "../../actions/profileActions";
import DisplayUser from "../../components/DisplayUser";
import DisplaySignUp from "../../components/DisplaySignUp";
import Spinner from "../../components/Spinner";
// using a PureComponent because we're not utilizing state,
// but we're utilizing the "componentDidMount" lifecycle
class Dashboard extends PureComponent {
componentDidMount = () => {
this.props.getCurrentProfile(1);
}
// the below can be read like so:
// if "isLoading" is true... then show a spinner
// else if "currentUser" is not empty... then display the user details
// else show a signup message
render = () => (
this.props.isLoading ? (
<Spinner />
) : !isEmpty(this.props.currentUser) ? (
<DisplayUser currentUser={this.props.currentUser} /> /
) : (
<DisplaySignUp />
)
}
// describing the shape of the "currentUser" object
// notice that there aren't any required declarations
// within the object itself because "currentUser" is initially
// an empty object; however, when it's not empty, it should
// follow this structure
Dashboard.propTypes = {
getCurrentProfile: PropTypes.func.isRequired,
currentUser: PropTypes.shape({
id: PropTypes.number,
name: PropTypes.string,
username: PropTypes.string,
email: PropTypes.string,
address: PropTypes.shape({
street: PropTypes.string,
suite: PropTypes.string,
city: PropTypes.string,
zipcode: PropTypes.string,
geo: PropTypes.objectOf(PropTypes.string)
}),
phone: PropTypes.string,
website: PropTypes.string,
company: PropTypes.objectOf(PropTypes.string)
}).isRequired,
isLoading: PropTypes.bool.isRequired
};
export default connect(
state => ({
currentUser: state.profile.currentUser,
isLoading: state.profile.isLoading
}),
{ getCurrentProfile }
)(Dashboard);
редукторы / profileReducer
import * as types from "../types";
const initialState = {
currentUser: {}, // setting currentUser initially as an empty object
isLoading: true // setting isLoading initially as a boolean
};
export default (state = initialState, { type, payload }) => {
switch (type) {
case types.SET_SIGNEDIN_USER:
return {
...state,
currentUser: { ...payload },
isLoading: false
};
default:
return state;
}
};