Загрузка HOC с проблемой Thunk с распространением реквизита - PullRequest
2 голосов
/ 06 октября 2019

Я создал HOC для загрузки. Он использует свойство isLoading, чтобы решить, что показывать.

Когда я открываю страницу прямо с URL, у меня нет проблем, и все работает нормально (потому что isLoading свойство установлено на true по умолчанию). Проблема в том, что когда я нажимаю на ссылку (<Link ... />), все работает не так, как ожидалось, потому что isLoading теперь false, потому что страница, на которой я перехожу, установила состояние на это значение.

Итак, это HOC:

import React from 'react';
export default function WithLoading(WrappedComponent, loadingDelegate) {
    class LoadingComponent extends React.Component {
        constructor(props) {

            super(props);
            this.state = {
                isLoading: true
            };
            this.loadingDelegate = loadingDelegate;
        }

        componentDidMount() {
            loadingDelegate(this);
        }

        render() {
            if (this.props.isLoading === true) {
                return (
                    <div>Loading...</div>
                );
            } else {
                return <WrappedComponent {...this.props} />;
            }
        }
    }

    return LoadingComponent;
}

И ниже компонента:

import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { actionCreators } from './SurveysStore';
import WithLoading from '../LoadingHOC';
//edit/:id
class SurveyDetailRoutedComponent extends React.Component {
    constructor(props) {
        super(props);
    }

    render() {
        return (
            <div>
                {this.props.survey.questions.length}
            </div>
        );
    }
}

const SurveyDetailRoutedComponentWithLoading = WithLoading(SurveyDetailRoutedComponent, (_context) => _context.props.requestSurvey(parseInt(_context.props.match.params.id)));
export default connect(
    state => state.surveysReducer,
    dispatch => bindActionCreators(actionCreators, dispatch)
)(SurveyDetailRoutedComponentWithLoading);

У меня ошибка в том, что survey является нулем, потому что я пытался отрисоватьНе определено свойство распознавателя.

Проблема возникает только в том случае, если я отображаю этот компонент с помощью <Link>, содержащегося на странице, отображаемой таким же образом .

Я пыталсяустановите isLoading=true в маршрутизации, но у меня это не работает:

export default class App extends React.Component {
    constructor(props) {
        super(props);
    }

    render() {
        return (
            <Layout>
                <Route exact path='/' component={(props) => <Home {...props} />} />
                <Route path='/survey/edit/:id' component={(props) => <SurveyDetailRoutedComponent {...props} isLoading={true} />} />
            </Layout>
        );
    }
}

Само хранилище очень простое, и я думаю, что моя ошибка в том, как я справляюсь с избыточностью, потому что она выглядит какоперация маршрутизации не сбрасывает загрузку.

const resetLoading = "RESET_LOADING";
const requestSurveys = "REQUEST_SURVEYS";
const receiveSurveys = "RECEIVE_SURVEYS";
const requestSurvey = "REQUEST_SURVEY";
const receiveSurvey = "RECEIVE_SURVEY";
const initialState = { surveys: [], isLoading: true, survey: null };
export const actionCreators = {
    resetLoading: () => function (dispatch, getState) {
        dispatch({ type: resetLoading })
    },
    requestSurveys: () => async function (dispatch, getState) {
        dispatch({ type: requestSurveys });
        const response = await fetch(...)
        const responseAsJson = await response.json();
        dispatch({ type: receiveSurveys, surveys: responseAsJson.data.surveys });
    },
    requestSurvey: id => async function (dispatch, getState) {
        dispatch({ type: requestSurvey });

        const response = await fetch(...)
        const responseAsJson = await response.json();
        dispatch({ type: receiveSurvey, survey: responseAsJson.data.survey });
    }
};

export const reducer = function(state, action) {
    state = state || initialState;
    switch (action.type) {
        case resetLoading:
            return {
                ...state,
                isLoading: true
            };
        case requestSurveys:
            return {
                ...state,
                isLoading: true
            };
        case requestSurvey:
            return {
                ...state,
                isLoading: true
            };
        case receiveSurveys:
            return {
                ...state,
                isLoading: false,
                surveys: action.surveys
            };
        case receiveSurvey:
            return {
                ...state,
                isLoading: false,
                survey: action.survey
            };
        default:
            return state;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...