Реагируйте один раз на вызов API для разработки нескольких маршрутов.

  • Я новичок в React и пытаюсь реализовать приложение. В основном мое приложение имеет несколько маршрутов. Каждый маршрут поддерживается одним и тем же набором внутренних данных + некоторые вызовы API, специфичные для маршрута, принимающие атрибуты данных конца в качестве параметров API.
  • Поэтому я написал компонент высшего порядка для вызова API для извлечения внутренних данных, сохранения состояния в хранилище избыточных данных и передачи его в качестве реквизита для обернутого компонента, который работает нормально.

    const withData = (WrappedComponent) => {
        class DataWrapper extends Component {
            constructor() {
                this.state = {
                    c: {},
                    d: []
                };
            }
    
        componentDidMount(){
            this.props.fetchData();
        }
    
        componentWillReceiveProps(nextProps){
            this.setState({
                c: nextProps.data.CSubset,
                d: nextProps.data.DSubset
            });
        }
    
        render() {
            return <WrappedComponent {...this.props} {...this.state}/>;
        }
        const mapStateToProps=(state)=>({
            data:state.appData
        });
    
        return connect(mapStateToProps,{fetchData})(DataWrapper);
    }
    
    export default withData;
    
    
    class AppComponent extends Component{
        componentDidMount(){
            this.props.fetchComponentSpecificData(c.dataAttribute);
        }
        render(){
            return <div />;
        }
    }
    
    export default connect(null,{fetchComponentSpecificData}(withData(AppComponent);
    
  • Но проблема в том, что API вызывается для всех маршрутов. Это должно быть один раз на полный поток приложения.

  • Выборка данных, специфичных для компонента, происходит до того, как становятся доступными общие внутренние данные, вызывая сбой вызова API, специфичного для компонента.
  • Пользователь может ввести URL-адрес и запустить любой маршрут в приложении, и API должен вызываться только один раз, а HOC должен систематически маршрутизировать правильный маршрут на основе данных. Посоветуйте пожалуйста подход к дизайну

1 ответ

Решение

Я бы сказал, что наиболее эффективным способом Reacty было бы реализовать глобальные вызовы API в componentWillMount метод компонента верхнего уровня (скажем, AppComponent). Прямо сейчас вы поместили его в компонент, который будет монтироваться для каждого подкомпонента вашего приложения, и может быть непросто предотвратить запуск вызова API при каждом монтировании.

Использование HOC для предоставления этих данных другим компонентам вашего приложения - неплохая идея, но оно делает ваше приложение немного более неявным, и я не думаю, что вы получаете много: вы добавляете компонент с неявным поведение вместо простого добавления строки в mapStateToProps.

Выполнение специфичных для страницы вызовов API после успешного вызова глобального API довольно сложно. Вам понадобится способ отслеживать тот факт, что глобальный вызов API разрешен, и в мышлении React/Redux это означает отправку действия. Для асинхронной отправки действий вам понадобится промежуточное ПО Redux, такое как redux-thunk или redux-saga (я считаю, что redux-thunk намного проще для новичков). Теперь, если у вас есть способ узнать, является ли глобальный вызов API успешным, вы можете дождаться отправки определенного действия (скажем, GLOBAL_API_CALL_SUCCESS). Теперь, это часть, где я делаю себе немного публичности: я написал https://github.com/Polyconseil/redux-waitfor-middleware, который позволяет вам ждать отправки конкретного действия. Если вы использовали его, это может выглядеть так:

export async function fetchComponentSpecificData() {
  await waitForMiddleware.waitFor([GLOBAL_API_CALL_SUCCESS]);

  // perform actual API call for this specific component here
}

Я не говорю, что промежуточное программное обеспечение waitFor - лучший инструмент для достижения этой цели, но, пожалуй, его легче всего понять, если вы только начинаете!

Другие вопросы по тегам