Флаг выборки не обновляется при использовании одного редуктора выборки - PullRequest
0 голосов
/ 07 августа 2020

Я очищаю свои флаги загрузки. Следуя рекомендациям , я использую отдельный редуктор для хранения всех флагов isFetching. При этом мне не нужно поддерживать несколько isFetchingFlags в моих редукторах.

Хотя я точно следил за объяснением, мой флаг isFetching не перескакивает с IsFetching: true (данные, получаемые в данный момент) на IsFetching: false (данные успешно загружен) в этой новой конфигурации. Мой флаг загрузки все время остается на IsFetching: false. Я проверил свой код несколько раз, но не могу найти свою ошибку.

Story Action:

// GET STORY
export const getStory = () => (dispatch, getState) => {
  dispatch ({type: GET_STORY_REQUEST});
  dispatch(showLoading());
  axios.get( apiBase + "/story/retrieve/", tokenConfig(getState))
    .then(res => {
      dispatch({
        type: GET_STORY_SUCCESS,
        payload: res.data
      });
      dispatch(hideLoading());
    })
  .catch(err =>{
      dispatch({
        payload: returnErrors(err.response.data, err.response.status),
        type: GET_STORY_FAILURE });
      dispatch(hideLoading());
    })
};

Loading Reducer

import {GET_STORY_SUCCESS,GET_STORY_REQUEST, GET_STORY_FAILURE} from "../actions/types.js";

const loadingReducer = (state = {}, action) => {
  const { type } = action;
  const matches = /(.*)_(REQUEST|SUCCESS|FAILURE)/.exec(type);
  
  // not a *_REQUEST / *_SUCCESS /  *_FAILURE actions, so we ignore them
  if (!matches) return state;  
  
  const [, requestName, requestState] = matches;
  return {
    ...state,
    // Store whether a request is happening at the moment or not
    // e.g. will be true when receiving GET_STORY_REQUEST
    //      and false when receiving GET_STORY_SUCCESS / GET_STORY_FAILURE
    [requestName]: requestState === 'REQUEST',
  };

Выбор загрузки

import _ from 'lodash';
export const createLoadingSelector = (actions) => (state) => {
  // returns true only when all actions is not loading
  return _(actions)
    .some((action) => _.get(state, `api.loading.${action}`));
};

Сюжетный компонент

import React, { Component, Fragment } from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { getStory} from '../../actions/story';
import { createLoadingSelector } from '../common/loading';




export class Story extends Component {

    static propTypes = {
      story: PropTypes.array.isRequired,
      getStory: PropTypes.func.isRequired,
   };

     componentDidMount() {
    this.props.getStory();
  }
  



  render() {
    const { story } = this.props.story;
   
    return (

  <Fragment>

        <h2>Stories</h2>

      </Fragment>

    );
  }
}


const loadingSelector = createLoadingSelector(['GET_STORY']);

function mapStateToProps(state, ownProps) {
    const story = state.story
    const isFetching = loadingSelector(state)
    console.log (isFetching)
    console.log (story)
  return { story, isFetching}
};


export default connect(
  mapStateToProps,
  { getStory}
)(Story);

Я рад каждому разъяснению.

1 Ответ

0 голосов
/ 07 августа 2020

Вы используете промежуточное ПО? Помните, что redux по умолчанию не поддерживает асинхронные действия. Если нет, попробуйте настроить промежуточное ПО redux-thunk.

https://github.com/reduxjs/redux-thunk

...