Реагируйте один раз на вызов 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 - лучший инструмент для достижения этой цели, но, пожалуй, его легче всего понять, если вы только начинаете!