Оптимизируйте усилия, необходимые для взаимодействия между вашим Redux Store и REST-подобным API. Это пакет функций создания действий и редукторов, созданный с помощью axios и промежуточного программного обеспечения redux-promise, которые управляют состоянием ресурсов за вас... все, что вам нужно, это URL-адрес!
Клиенты инкапсулируют API, который вы используете. Вы можете создать нового клиента, указав базовый URL-адрес API.
import { createClient } из 'redux-supermodel'const client = createClient('https://example.com/api/v1')
В вашем клиенте вы можете начать определять ресурсы. Каждый ресурс представляет собой конечную точку, с которой вы можете взаимодействовать.
// Полный URL-адрес будет https://example.com/api/v1/blogsconst blogs = client('blogs')// https://example.com/api/v1/commentsconst comment = client('comments' )
Начните с определения ресурса. Предположим, http://example.com/api/posts/latest
вернет объект JSON со свойствами title
и body
.
// resources.jsimport { createClient } из 'redux-supermodel'const client = createClient('http://example.com/api')// GET http://example.com/api/posts/latest/// / { title: «Моя последняя запись в блоге», body: «Привет, мир!» }export const post = client('post', {url: 'posts/latest' }) post.fetch()
Вы можете использовать компонент высшего порядка connect
, чтобы прикрепить состояние вашего ресурса к вашему компоненту и связать любые создатели действий, которые вы хотите использовать. Большую часть времени вы будете что-то получать, когда компонент монтируется. Если это единственный компонент, который будет использовать ресурс, вы можете сбросить его при размонтировании компонента. Обычно создатели действий create
и update
будут привязаны к кнопке или обработчикам отправки в вашей форме.
// MyComponent.jsimport React, { Component } from 'react'import {connect } from 'react-redux'import { post } from './resources'export class MyComponent расширяет компонент { асинхронный компонентDidMount() { try { const res = await this.props.fetchPost() // Создатели действий AJAX — это промисы, поэтому вы можете ожидать их выполнения, // чтобы обработать ошибки или сделать что-нибудь после их завершения. console.log(res)} catch (error) { // redux-supermodel будет отслеживать состояние ошибки за вас, но // вы также можете делать что-то свое. alert('Произошло что-то плохое!')} } // Если вы когда-либо обращаетесь к ресурсу только в контексте одного компонента и // его дочерние элементы, вы можете сбросить ресурс при размонтировании, чтобы очистить состояние избыточности. компонентWillUnmount = () => this.props.resetPost() render() {const { инициализировано, error, title, body, fetchPost } = this.propsif (!initialized) { if (error) {return <div className="error">{error.message</div> } else {return <div className="loading">Загрузка...</div> }}return ( <div><h1>{title}</h1><div className="body"> {body}</div><div className="error"> {error.message</div>< button type="button" onClick={fetchPost}>Обновить</button> </div>) }} функция экспорта MapProps (состояние) { const {готово, ошибка, полезная нагрузка} = сообщение (состояние) const { data: { title, body } = {} } = полезная нагрузка return {готово, ошибка, заголовок, тело }}const action = { fetchPost: () => post.fetch({ id: 'latest' }), resetPost: post.reset,}export default Connect (mapProps, Actions) (MyComponent)
Полезная нагрузка может представлять собой массивный объект, содержащий много информации о HTTP-запросе и ответе, большая часть которой вам не понадобится при рендеринге компонента, поэтому я предлагаю использовать вызов mapProps
, чтобы упростить полезную нагрузку до вещи, которые вам понадобятся. Старайтесь избегать прямого использования полезной нагрузки. Прочтите этот пост в блоге для дальнейшего чтения.
Подробную информацию о MapProps можно найти в документации по реагированию на соединение().
npm install --save redux-supermodel redux-promise-middleware
Вам нужно будет добавить промежуточное программное обеспечение redux-promise-middleware
и редуктор redux-supermodel
в ваш Redux Store.
// store.jsimport { createStore, applyMiddleware, Compose, ComposeReducers } из 'redux'import по умолчанию compose(applyMiddleware(promiseMiddleware()))(createStore)(rootReducer)