#reactjs #redux #react-redux
#reactjs #сокращение #react-redux
Вопрос:
В настоящее время я собираюсь узнать, как использовать флаги выборки для извлечения асинхронных данных. Флаг выборки работает хорошо. Но даже если isFetching=false
, это означает, что profile
данные недоступны. React выдает мне ошибку о том, что оно не определено:
Unhandled Rejection (TypeError): Cannot read property 'data' of undefined
Компонент заголовка
export class Header extends Component {
render() {
const { isAuthenticated } = this.props.auth;
const profile = this.props.profile;
const isFetching = this.props.isFetching
console.log (isFetching)
console.log (profile);
// Data is fetching
if (isFetching === true) return (<h1>Loading ...</h1>);
// Data is ready: Here the username within the profile is called.
if (isFetching === false ) return (<h1> Hallo {profile[0].username} </h1>);
}
}
const loadingSelector = createLoadingSelector(['GET_USER', 'GET_PROFILE']);
function mapStateToProps(state, ownProps) {
const auth = state.auth
const profile = state.profile
const isFetching = loadingSelector(state)
return { auth, profile, isFetching}
};
export default connect(
mapStateToProps,
{ logout }
)(Header);
Действие профиля
export const getProfile = () => (dispatch, getState) => {
// Profile Loading
dispatch({ type: GET_PROFILE_REQUEST });
dispatch(showLoading());
axios
.get(apiBase "/profile/", tokenConfig(getState))
.then(res => {
dispatch({
type: GET_PROFILE_SUCCESS,
payload: res.data
});
dispatch(hideLoading())
})
.catch((err) => {
dispatch(returnErrors(err.response.data, err.response.status));
dispatch({
type: GET_PROFILE_FAILURE,
});
dispatch(hideLoading())
});
};
Профилирующие редукторы
const initialState = {
profile: null
};
export default function(state = initialState, action) {
switch (action.type) {
case GET_PROFILE_REQUEST:
return {
...state,
};
case GET_PROFILE_SUCCESS:
return {
...state,
profile: action.payload,
};
case GET_PROFILE_FAILURE:
return {
...state,
profile: action.payload,
};
default:
return state;
}
}
Журнал консоли: Перед запуском процесса выборки флаг выборки равен false, пока профиль не готов.
header.js:16 false // isFetching
header.js:18 {profile: null}
header.js:16 true // isFetching
header.js:18 {profile: null}
header.js:16 true // isFetching
header.js:18 {profile: null}
header.js:16 false // isFetching
header.js:18 {profile: Array(1)}
Почему данные не готовы (не определены), даже если флаг выборки указывает, что они должны быть доступны?
Я рад любым разъяснениям.
Редактировать Я упростил свой код-sinppet и добавил создатель действия и редуктор. Создатель действия вызывается в App.js. Я также думаю, что ошибка вызвана из-за того, что в самом начале isFetching=false
(см. Журнал консоли), в то время как данные профиля все еще null
. Это может привести к ошибке.
Но как мне учесть это пространственное состояние в моем компоненте?
Комментарии:
1. Что такое «данные» в ваших фрагментах кода? Нет
data
идентификатора. Возможно ли, что в редукторе что-то не определено? Пожалуйста, укажите создателей действий и код редуктора.Unhandled Rejection
обычно означает, что где-то есть цепочка обещаний, выдающая отклонение, которое ваш код не обрабатывает черезcatch
блок.2. @DrewReese Спасибо тебе. Я добавил фрагменты кода, которые вы просили. Данные находятся в моем профиле case, я разъяснил это в своем посте. Я предполагаю, что ошибка вызвана тем, что в самом начале параметр is fetching имеет значение false (см. Журнал консоли), в то время как профиль равен null. Таким образом, переход к условному отображению для
if (isFetching=f==false) return({profile[0].username})
даже еслиprofile
значение не равно null. Теперь мне интересно, как я могу объяснить этот случай?
Ответ №1:
изначально isFetching = false возвращает нулевой объект, который вы пытаетесь отобразить, он выдает ошибку, поскольку профиль еще не загружен, если вы можете изменить свою часть рендеринга, как показано ниже, вы можете достичь требуемого
export class Header extends Component {
render() {
const { isAuthenticated } = this.props.auth;
let profile=[]
if(this.props.profile!==null){
profile = this.props.profile;
}
const isFetching = this.props.isFetching
console.log (isFetching)
console.log (profile);
if (isFetching === true) return (<h1>Loading ...</h1>);
if (isFetching === false ) return
(<h1>
Hallo {profile.length>1?
{profile[0].username}:null} </h1>); //initially it renders profile once it is available
}
}
Комментарии:
1. Спасибо за ответ. Это работает. Возможно ли поместить
{profile.length>1? {profile[0].username}:null}
в функцию `if` в качестве дополнительного условия, чтобы мне приходилось выполнять эту проверку только один раз и не всегда, когда я хочу получить доступ к некоторому массиву профилей данных?2. профиль изначально равен нулю, а затем доступен, вы должны использовать его вышеуказанным способом, если вы не хотите изменить начальное состояние на true (состояние из redux)