Как использовать Redux-Saga с Hooks для вызова API - PullRequest
1 голос
/ 10 февраля 2020

Я пытаюсь использовать промежуточное ПО Redux-saga, чтобы избежать ошибки функций asyn c, я использую React Hooks, я подключил Redux-Saga и выполнил функцию * yield, но не знаю, почему это не так чтение моего действия, чтобы перехватить его, и это дает мне ту же ошибку:

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

Код: Store. js

import createSagaMiddleware from 'redux-saga';
import rootReducer from './RootReducer'
import {watchFetchImages} from '../middleware/saga';

const sagaMiddleware = createSagaMiddleware();
const store = createStore(
    rootReducer,
    applyMiddleware(sagaMiddleware)
  );
  sagaMiddleware.run(watchFetchImages);

export default store;

Actions. js

import axios from 'axios';
import { GetCategories } from './actionTypes'
import {GetImages} from './actionTypes'

export function fetchCategories() {
    var url = 'http://localhost:4000/all_categories';
    return (dispatch) => {
        return axios.get(url).then((res) => {
            dispatch({
                type: GetCategories,
                payload: res.data
            })
        })
    } 
}


export function fetchImages(){
    var url ='/all_categories';
    return(dispatch) => {
        return axios.get(url).then((res)=>{
            dispatch({
                type:GetImages,
                payload:res.data
            })  

        })
    }
}

Редукторы . js

import { GetCategories , GetImages } from "../redux/actions/actionTypes"
const initialState = {
    categories: [],
    images:[]
};

const rootReducer = (state = initialState, action) => {
    switch (action.type) {
        case GetCategories:
            return {...state, categories: state.categories.concat(action.payload)}
        case GetImages:
            return{...state,images:action.payload}
        default:
        return state;

    }
};
export default rootReducer;

Сага. js

import {takeEvery,delay} from 'redux-saga/effects'



function* getImagesAsync(){
    yield delay(4000);
    console.log('api called')


}
export function* watchFetchImages(){

    yield takeEvery("GetImages",getImagesAsync);


}

Дом. js Где я называю действие приведения

const  HomePage = props => {



    useEffect(()=>props.getImages())
    console.log(props)

 const mapStateToProps = (images) => ({
        images
    })
    const mapDispatchToProps= dispatch =>({

        getImages: () => dispatch(fetchImages())
    })

export default connect(mapStateToProps,mapDispatchToProps)(HomePage);

Индекс. js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { Provider } from "react-redux";
import store from '../src/redux/store';
import * as serviceWorker from './serviceWorker';

ReactDOM.render(<Provider store={store}><App /></Provider>, document.getElementById('root'));


Кто-нибудь может мне помочь с этим ??

Ответы [ 2 ]

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

Так что я не вижу проблем с настройкой store, applyMiddleware находится на правильном месте. Проблема, которую я вижу, заключается в функциях генератора, которые вы можете вызвать dispatch, однако есть несколько недостатков, которые читаются далее: Отправка действий в хранилище .

Вместо этого вы можете вызвать put для диспетчерские действия. создающий эффект промежуточное ПО позаботится об этом и отправит соответствующее действие в магазин. Таким образом, в качестве лучшего решения из документации , которая гласит:

Вместо этого нам нужно такое же декларативное решение. Создайте простой JavaScript объект, чтобы указать промежуточному программному обеспечению, что нам нужно выполнить какое-либо действие, и дайте промежуточному программному обеспечению выполнить настоящую диспетчеризацию. Таким образом, мы можем проверить диспетчеризацию Генератора таким же образом: проверив полученный эффект и убедившись, что он содержит правильные инструкции.

Для этой цели библиотека предоставляет еще одну функцию, которая создает эффект диспетчеризации.

Попробуйте внести следующие изменения в Saga.js:

function* getImagesAsync() {
    // here you can call your API
    const payloadImages = // result from API response

    yield put({type: 'GetImages', payloadImages});
}

export default function* watchFetchImages() {
    yield takeEvery('GetImages', getImagesAsync);
}

Надеюсь, это поможет!

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

Я только что несколько недель работал над проектом go, в котором для редукции веб-сокетов используется redux-saga, и у меня возникла почти симулированная проблема. SageMidddleware действительно работает для сага-функций, но для использования функций для действий я использую redux-thrunk. Маленький пример:

import { 
	createStore, 
	applyMiddleware, 
	compose 
} from "redux";

import createSagaMiddleware from 'redux-saga'; 
import thunk from "redux-thunk"; 

import reducer from '../reducers';

const storeEnhancers =  window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;

const store = createStore(
	reducer,
	(localStorage['storage']) ? JSON.parse(localStorage['storage']) : {},
	storeEnhancers(applyMiddleware(sagaMiddleware, thunk))
);

Надеюсь, это поможет вам любым возможным способом.

...