Действия должны быть простыми объектами. Использовать пользовательское промежуточное ПО для действий asyn c Saga Thunk, который у меня есть в моем магазине - PullRequest
0 голосов
/ 06 января 2020

Проблема в следующем:

Я пытаюсь использовать redux-saga в своем приложении реакции, но у меня все еще есть эта ошибка: Действия должны быть простыми объектами. Используйте пользовательское промежуточное программное обеспечение для действий asyn c. Код кажется правильным, но не знаю, почему выдает эту ошибку. Я буду рад за любую помощь. Я борюсь с этим около двух дней и до сих пор не могу найти решение. Я попытался посмотреть, но у меня все еще есть эта ошибка.

action...
import { GET_DISTRICTS} from '../../constants';

const getAdres = async (url) => {
    let response = await fetch(url);
    let data = await response.json();
    let list = [];
    data.AdresList.Adresler.Adres.forEach((item) => {
        console.info(item);
        list.push({
            label: item.ADI,
            value: item.ID
        });
    });
    return list;
};

export const actions = {
    handleGetDistrictsData: async () => {
        let districts = await getAdres(`url is here`);

        return {
            type: GET_DISTRICTS,
            payload: districts
        };
    },

reducer...
import { GET_DISTRICTS } from '../../constants';

export const initialState = {
    districts: [],
    quarters: [],
    streets: [],
    doors: [],
    districtSelected: false,
    districtSelectedID: null,
    quarterSelected: false,
    quarterSelectedID: null,
    streetSelected: false,
    streetSelectedID: null,
    doorSelected: false,
    doorSelectedID: null
};

export default (state = initialState, action) => {
    switch (action.type) {
        case GET_DISTRICTS:
            return {
                ...state,
                districts: action.payload
            };
        default:
            return state;
    }
};


component...
import React, { useEffect, useState } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { actions as addressActions } from '../../../../redux/actions/address';

import Select from 'react-select';

const Districts = (props) => {
    let [ fetchedData, setFetchedData ] = useState(false);

    useEffect(() => {
        props.handleGetDistrictsData();
        setFetchedData(true);
    });

    return (
        <React.Fragment>
            <Select
                name='adresSelect'
                options={props.address.districts}
                onChange={props.handleDistrictChange}
                placeholder='Please Select'
            />
        </React.Fragment>
    );
};

const mapStateToProps = (state) => ({
    address: state.address
});

const mapDispatchToProps = function(dispatch) {
    return bindActionCreators({ ...addressActions }, dispatch);
};

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

-------------

import React from 'react';

import Districts from './Districts';

const AddressSearchWidget = (props) => {
    return (
        <React.Fragment>
            <Districts />
        </React.Fragment>
    );
};

export default AddressSearchWidget


store...
import { applyMiddleware, combineReducers, compose, createStore } from 'redux';
import createSagaMiddleware from 'redux-saga';
import rootSaga from './sagas/index';

import * as reducers from './';

export function initStore() {
    const composeEnhancer = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;

    const rootReducer = combineReducers(reducers);
    const sagaMiddleware = createSagaMiddleware();

    const store = createStore(rootReducer, composeEnhancer(applyMiddleware(sagaMiddleware)));

    // Run sagas
    sagaMiddleware.run(rootSaga);

    return store;
}

1 Ответ

2 голосов
/ 06 января 2020

handleGetDistrictsData возвращает обещание (все функции asyn c возвращают обещания). Вы не можете отправить обещание в простой саге о редуксе, и суть о редуксе не меняет этого. Вместо этого отправьте обычное действие и запустите сагу. После этого сага может делать асин c вещи, а когда это сделано, отправлять другое действие. Редуктор слушает только это второе действие.

// Actions:
export const getDistrictsData = () => ({
  type: GET_DISTRICTS,
})

export const districtsDataSuccess = (districts) => ({
  type: DISTRICTS_DATA_SUCCESS,
  payload: districts
})

// Sagas:
export function* watchGetDistricts () {
  takeEvery(GET_DISTRICTS, getDistricts);
}

function* getDistricts() {
    let response = yield fetch(url);
    let data = yield response.json();
    let list = [];
    data.AdresList.Adresler.Adres.forEach((item) => {
        console.info(item);
        list.push({
            label: item.ADI,
            value: item.ID
        });
    });
    yield put(districtsDataSuccess(list));
}

// reducer:
export default (state = initialState, action) => {
    switch (action.type) {
        case DISTRICTS_DATA_SUCCESS:
            return {
                ...state,
                districts: action.payload
            };
        default:
            return state;
    }
};
...