React -Redux: почему данные не готовы, даже если выборка завершена?

#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)