Как создать собственное промежуточное ПО для asyn c запроса и редукса? - PullRequest
0 голосов
/ 09 февраля 2020

Помогите понять в чем проблема. Когда я пишу mapDispatchToProps следующим образом:

const mapDispatchToProps = (dispatch: any) => {
    return {
        getPostByIdAction: (post: any) => dispatch ({type: GET_ID, payload: post})
    }
};

все работает нормально. Но когда я пытаюсь отправить функцию следующим образом:

const mapDispatchToProps = (dispatch: any) => {
    return {
        getPostByIdAction: (post: any) => dispatch (getPostById (post))
    }
};

я получаю сообщение об ошибке: Действия должны быть простыми объектами. Используйте пользовательское промежуточное программное обеспечение для действий asyn c. Что могло пойти не так?

мои действия:

export const getPostById = async (id: any) => {
    const myResponse = await fetch (`https://jsonplaceholder.typicode.com/posts/$ {id}`);
    const myJson = await myResponse.json ();
    const post = myJson.body
}

мой редуктор:

import {combineReducers} from 'redux'
import {pageReducer} from './page'


export const rootReducer = combineReducers ({
  page: pageReducer
})
import {GET_ID} from '../actions/PageActions'

const initialState = {
    post: "Click on article to read it"
}

export function pageReducer (state = initialState, action: any) {
    switch (action.type) {
        case GET_ID:
            return {... state, post: action.payload};
        default:
            return state
    }
}

Ответы [ 2 ]

0 голосов
/ 11 февраля 2020

Основная проблема с избыточностью заключается в том, что .., это синхронно. Для обработки асинхронных c операций мы используем промежуточное ПО. Для обработки асин c доступно множество библиотек.

Но, если вы хотите создать его, давайте создадим пользовательское промежуточное ПО для асинхронных c операций

Я определил некоторые типы для безопасности типов (так как мы делаем это в машинописи ). Здесь мы добавили еще одно поле 'api' для нашего удобства, чтобы дифференцировать асин c операции с не-асин c од

import { Middleware, Dispatch, MiddlewareAPI } from 'redux'


export interface DispatchType {
    type: string
    payload?: any
    meta?: DispatchMeta
}

export interface DispatchMeta {
    async: boolean
    api: {
        url: string
        onComplete: string
        // extra information you want for the request can be passes here:
        // eg
        // params, method, data
    }
}

Тип объекта, который мы отправляем, выглядит примерно так:

dispatch({type: 'TYPE_OF_DISPATCH', payload: 'any type of payload'})

Теперь давайте создадим промежуточное программное обеспечение для перехвата тех действий (объекта), для которых мета-поле с asyn c установлено в значение «истина».


// Middleware to intercept those actions(object) that has meta field with async set to true;

export const asyncMiddleware: Middleware = ({ getState }: MiddlewareAPI) => (
    next: Dispatch
) => async (action: DispatchType) => {


    // Call the next dispatch method in the middleware chain.
    next(action);

    if (action.meta && action.meta.async && action.meta.api) {
        const res = await fetch(action.meta.api.url);
        const json = await res.json();
        const post = json.body;
        next({
            type: action.meta.api.onComplete,
            data: post
        })
    }


}

Здесь наше промежуточное программное обеспечение перехватывает действие с помощью asyn c флаг 'true' и затем после его завершения отправляет действие 'onComplete', отправленное мета.

Чтобы использовать это промежуточное ПО, ваше действие отправки должно выглядеть примерно так

dispatch({
  type: 'FETCH',
    meta: {
        async: true,
        api: {
            url: 'https://jsonplaceholder.typicode.com/posts/1',
            onComplete: 'FETCHED_POST'
        }
    }
})

Здесь вы можете создать функцию-обертку, которая отправляет вышеуказанное действие

const getpost = (id: string) => 
   dispatch({
          type: 'FETCH',
            meta: {
                async: true,
                api: {
                    url: `https://jsonplaceholder.typicode.com/posts/${id}`,
                    onComplete: 'FETCHED_POST'
                }
            }
        })   

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

const store = createStore(
    RootReducer,
    applyMiddleware(asyncMiddleware)
)
0 голосов
/ 11 февраля 2020
export const getPostById = async (id: any) => {
    const myResponse = await fetch (`https://jsonplaceholder.typicode.com/posts/$ {id}`);
    const myJson = await myResponse.json ();
    const post = myJson.body
}

вы ничего не возвращаете. Вы должны вернуть объект здесь, чтобы передать его для отправки. Для отправки требуется объект, и этот объект должен иметь свойство «действие». Вы можете добавить больше свойств, но свойство "action" обязательно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...