Как остановить перезагрузку компонента реакции с помощью isLoading в React - PullRequest
0 голосов
/ 15 марта 2020

В моем приложении реакции у меня есть страница панели инструментов, подобная этой.

import React, { useEffect } from 'react';

import { DashboardContent } from 'components';
import { Text } from 'components/ui';

import './dashboard.styles.scss';

const DashboardPage = ({ user, profile, getAuthProfileStart }: IProps) => {
  console.log('reloading the page...');
  useEffect(() => {
    getAuthProfileStart();
  }, []);

  const deleteExperience = () => {
    return 'Experience Deleted';
  };
  const deleteEducation = () => {
    return 'Education Deleted';
  };
  const deleteAccount = () => {
    return 'Account Deleted';
  };

  return (
    <div className='dashboard'>
      <div className='content'>
        <Text Type='h1' className='title' text='Dashboard' />

        <DashboardContent
          user={user}
          profile={profile}
          deleteExperience={deleteExperience}
          deleteEducation={deleteEducation}
          deleteAccount={deleteAccount}
        />
      </div>
    </div>
  );
};

interface IProps {
  user: any;
  profile: any;
  getAuthProfileStart: Function;
}

export default DashboardPage;

Контейнер панели инструментов выглядит следующим образом.

import { connect } from 'react-redux';
import { compose } from 'redux';

import { WithSpinner } from 'components/ui';
import Dashboard from './dashboard.page';

import { IReduxState } from 'types/reducer.types';

import * as alertActions from 'redux/alert/alert.actions';
import * as profileActions from 'redux/profile/profle.actions';

const mapStateToProps = ({
  auth: { user },
  profile: { authProfile, profileFetching },
}: IReduxState) => ({
  user,
  profile: authProfile,
  isLoading: profileFetching,
});

const actions = {
  startAlert: alertActions.startAlert,
  getAuthProfileStart: profileActions.getAuthProfileStart,
};

export default compose(connect(mapStateToProps, actions), WithSpinner)(Dashboard);

WithSpinner - это HO C код выглядит следующим образом.

import React from 'react';

import './with-spinner.styles.scss';

const WithSpinner = (WrappedComponent: any) => {
  const Spinner = ({ isLoading, ...otherProps }: IProps) => {
    return isLoading && WrappedComponent ? (
      <div className='spinner-overlay'>
        <div className='spinner-container' />
      </div>
    ) : (
      <WrappedComponent {...otherProps} />
    );
  };

  return Spinner;
};

interface IProps {
  isLoading: boolean;
}

export default WithSpinner;

Это действия профиля.

import { profileTypes } from 'redux/profile/profile.constants';

export const getAuthProfileStart = () => ({
  type: profileTypes.GET_AUTH_PROFILE_START,
});

export const getAuthProfileSuccess = (payload: Object) => ({
  type: profileTypes.GET_AUTH_PROFILE_SUCCESS,
  payload,
});

export const getAuthProfileError = (payload: Object) => ({
  type: profileTypes.GET_AUTH_PROFILE_ERROR,
  payload,
});

Вот сага профиля.

import { call, put, select, takeLatest } from 'redux-saga/effects';

// import { alert } from 'enums/alert.enum';
// import { startAlert } from 'redux/alert/alert.actions';
import { profileTypes } from 'redux/profile/profile.constants';
import { IProfile } from 'types/profile.types';
import { IReduxState } from 'types/reducer.types';

import ProfileHttp from './profile.http';

import { getAuthProfileError, getAuthProfileSuccess } from 'redux/profile/profle.actions';

const getToken = (state: IReduxState) => state.auth.token;

export function* getAuthProfileStart() {
  try {
    const token = yield select(getToken);
    const { data } = yield call(ProfileHttp.getAuthProfile, token);
    const mappedResponse: IProfile = data;
    yield put(getAuthProfileSuccess(mappedResponse));
  } catch (ex) {
    yield put(getAuthProfileError(ex.error));
  }
}

export default function* profileSaga() {
  yield takeLatest(profileTypes.GET_AUTH_PROFILE_START, getAuthProfileStart);
}

Наконец, это профиль редуктора.

import { authTypes } from 'redux/auth/auth.constants';
import { profileTypes } from 'redux/profile/profile.constants';
import { IAction } from 'types/common.types';
import { IProfileReducer } from 'types/reducer.types';

const INITIAL_STATE = {
  authProfile: '',
  profiles: [],
  repos: [],
  profileFetching: false,
  error: '',
};

export default (state = INITIAL_STATE, { type, payload }: IAction) => {
  switch (type) {
    case profileTypes.GET_AUTH_PROFILE_START:
      return startFetchingProfile(state);

    case profileTypes.GET_AUTH_PROFILE_SUCCESS:
      return setAuthProfileSuccess(state, payload);

    case profileTypes.GET_AUTH_PROFILE_ERROR:
      return setAuthProfileError(state, payload);

    case authTypes.SIGN_OUT:
      return signOut();

    default:
      return state;
  }
};

const startFetchingProfile = (state: IProfileReducer) => ({
  ...state,
  profileFetching: true,
});

const setAuthProfileSuccess = (state: IProfileReducer, payload: Object) => ({
  ...state,
  authProfile: payload,
  profileFetching: false,
  error: '',
});

const setAuthProfileError = (state: IProfileReducer, payload: Object) => ({
  ...state,
  authProfile: '',
  profileFetching: false,
  error: payload,
});

const signOut = () => ({
  ...INITIAL_STATE,
});

Здесь проблема заключается в том, что при загрузке страницы панели инструментов отображается счетчик. Но одно за другим действия getAuthProfileSuccess и getAuthProfileStart отправляются до тех пор, пока не произойдет сбой страницы. Что я здесь не так делаю? После отправки одного действия getAuthProfileSuccess я установил для profileFetching значение false, поэтому значение isLoading должно быть равно false в компоненте WithSpinner. Так что приемный компонент к HO C должен отображаться вместо счетчика.

В чем причина перезагрузки моей страницы панели инструментов?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...