redux-saga:动作必须是普通对象

时间:2018-10-12 20:43:55

标签: reactjs react-redux redux-saga

我的传奇故事有问题,我不知道哪里出了问题。我收到类似操作之类的错误,必须是普通对象。在使用React Redux时,将自定义中间件用于异步操作。这是我的代码。

container / index.js

class AppContainer extends Component {

    componentDidMount() {
        const { actions: { onFetchPhoto } } = this.props;
        onFetchPhoto();
    }

    render() {
        return (
            <App />
        );
    }
}


const mapDispatchToProps = (dispatch) => ({
    actions: {
        onFetchPhoto: () => dispatch(fetchPhoto())
    }
})


export default connect(null, mapDispatchToProps)(AppContainer);

actions / index.js

export const FETCH_PHOTO_REQUEST = "FETCH_PHOTO_REQUEST";
export const FETCH_PHOTO_SUCCESS = "FETCH_PHOTO_SUCCESS";
export const FETCH_PHOTO_FAILURE = "FETCH_PHOTO_FAILURE";

export function fetchPhoto(payload) {
    return {
        type: FETCH_PHOTO_REQUEST
    }
}
export function fetchPhotoSuccess(payload) {
    return {
        type: FETCH_PHOTO_SUCCESS,
        payload
    }
}
export function fetchPhotoFailure(error) {
    return {
        type: FETCH_PHOTO_SUCCESS,
        payload: {
            error
        }
    }
}

sagas / index.js

function* fetchRandomPhoto() {
    //yield put(fetchPhoto());

    const {
        response,
        error
    } = yield call(fetchRandomPhotoApi)

    if (response) {
        yield put(fetchPhotoSuccess(response))
    } else {
        yield put(fetchPhotoFailure(error))
    }
}

function* watchLoadRandomPhoto() {
    try {
        while (true) {
            yield takeLatest(FETCH_PHOTO_REQUEST, fetchRandomPhoto);
        }
    }
    catch(error) {
        console.error("error in saga", error)
    }
}

export default function* rootSaga() {
    yield fork(watchLoadRandomPhoto)
}

services / index.js

import axios from 'axios';
import {
    URL,
    PUBLIC_KEY
} from 'src/constants/config';

import {
    schema,
    normalize
} from 'normalizr'

export function fetchRandomPhotoApi() {
    return axios({
            url: `${URL}/photos/random`,
            timeout: 10000,
            method: 'get',
            headers: {
                'Autorization': `Client-ID ${PUBLIC_KEY}`
            },
            responseType: 'json'
        })
        .then((response) => {
            const { data } = response.data;
            console.log("d");
            if (data) {
                return ({
                    response: {
                        id: data.id,
                        url: data.urls.full,
                        title: data.location.title
                    }
                })
            }
        })
       .catch(error => error)
}

store / configureStore.js

import rootReducer from 'src/reducers/root';
import rootSaga from 'src/sagas';


export default function configureStore() {
    const logger = createLogger();
    const sagaMiddleware = createSagaMiddleware();
    const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;

    const store = createStore(
        rootReducer,
        compose(
            applyMiddleware(
                sagaMiddleware,
                logger,
                composeEnhancers
            ),
        )
    );

    sagaMiddleware.run(rootSaga);

    return store;
}

我浪费了2天的时间来解决此问题,但没有结果。 Chrome向我显示了此错误:

enter image description here

2 个答案:

答案 0 :(得分:0)

问题的根源位于fetchRandomPhotoApi函数中。不知道是什么样子我不能肯定地说,但是例如,如果它是一个返回promise的函数,您应该像这样

const { response, error } = yield call(fetchRandomPhotoApi)

请注意通话中没有括号。

更新

从您的编辑中,我现在可以看到在您的api调用中未解决诺言。您希望该函数返回一个对象,而不是传递给操作的实际承诺。符合以下条件的东西:

axios({...etc}).then(response => response).catch(error => error)

答案 1 :(得分:0)

好吧,我发现了我的问题,但是我不明白为什么。我添加了这段代码。

store / index.js

export default function configureStore() {
    const logger = createLogger();
    const sagaMiddleware = createSagaMiddleware();
    const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;

    const store = createStore(
        rootReducer,
        compose(
            applyMiddleware(
                sagaMiddleware,
                logger
            ),
            window.__REDUX_DEVTOOLS_EXTENSION__ ? window.__REDUX_DEVTOOLS_EXTENSION__() : (fn) => fn
        )
    );

    store.runSaga = sagaMiddleware.run;

    return store;
}

index.js

import React from 'react';
import ReactDOM from 'react-dom';

import { Provider } from 'react-redux';

import configureStore from 'src/store/configureStore';

import Routes from 'src/routes/root';
import rootSaga from 'src/sagas';

const store = configureStore();

store.runSaga(rootSaga);

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

这行代码也使我的应用正常工作。

window.__REDUX_DEVTOOLS_EXTENSION__ ? window.__REDUX_DEVTOOLS_EXTENSION__() : (fn) => fn