简体   繁体   English

使用 redux saga 获取数据

[英]Fetch data with redux saga

I have created an example for fetching data from API where I used redux-thunk .我创建了一个示例,用于从使用redux-thunk API 获取数据。 The following code is working.以下代码正在运行。

In this context, I want to rewrite my code but using redux saga .在这种情况下,我想重写我的代码,但使用redux saga

 import React from 'react'; import {createStore, applyMiddleware} from 'redux'; import ReactDOM from "react-dom"; import thunk from 'redux-thunk'; import axios from 'axios'; function App(props) { const initialState = { loading: false, data: [], error: '' }; const reducer = function (state = initialState, action) { switch (action.type) { case 'START_FETCH': return { ...state, loading: true }; case 'PROCESS_FETCH': return { ...state, loading: false, data: action.payload, error: "" }; case 'END_FETCH': return { ...state, loading: false, data: [], error: action.payload } } return state; }; const START_FETCH = 'START_FETCH'; const PROCESS_FETCH = 'PROCESS_FETCH'; const END_FETCH = 'END_FETCH'; let startFetchFun = () => { return { type: START_FETCH, loading: true } }; let processFetchFun = (users) => { return { type: PROCESS_FETCH, payload: users } }; let endFetchFun = (error) => { return { type: PROCESS_FETCH, payload: error } }; let fetchUsersWithThunk = () => { return function (dispatch) { dispatch(startFetchFun()); axios.get('https://jsonplaceholder.typicode.com/users') .then((response) => { dispatch(processFetchFun(response.data)); }) .catch((error) => { dispatch(endFetchFun(error.message)); console.log(error.message); }) } }; const store = createStore(reducer, applyMiddleware(thunk)); store.subscribe(() => { console.log(store.getState()) }); store.dispatch(fetchUsersWithThunk()); return ( <div className="main"> <h1>Redux-Thunk</h1> </div> ); } ReactDOM.render( <App/>, document.getElementById('root'));

I want to write the code above using redux saga, to understand better sagas.我想使用 redux saga 编写上面的代码,以更好地理解 saga。 So, how to use redux-saga for this example?那么,如何在这个例子中使用 redux-saga 呢? Who will be able to help me?谁能帮助我?

Redux Saga uses yield call to call promises like an api service and uses yield put to dispatch actions to the store. Redux Saga 使用yield call像 API 服务一样调用 promise,并使用yield put将操作分派到 store。

The difference is about blocking and not blocking calls.区别在于阻塞和不阻塞调用。 Because we want to wait for the server to respond our request we will use yield call that is a blocking function.因为我们想等待服务器响应我们的请求,所以我们将使用作为阻塞函数的yield call Instead of dispatching the action directly inside the generator saga uses yield put({ type: "actionName" }) .使用yield put({ type: "actionName" })代替直接在 generator saga 内分派动作。 That's also useful for testing purposese.这对于测试目的也很有用。

So you should wrote your saga as following:所以你应该写你的传奇如下:

import {all, fork, put, call, takeLatest} from 'redux-saga/effects';

function* handleRequest (action) {
  try {
    yield put(startFetchFunc()); // dispatch the action to the store.
    const result = yiels call(apiService.users, [data to pass]); // wait for the response blocking the code execution.
    yield put(processFetchFun(result)); // dispatch the action to the store containing  the data
   } catch (e) {
    yield put(endFetchFun('Error'));
   }
}

function* watchRequest() {
   yield takeLatest({type: "START_FETCH"}, handleRequest);
}

export function* rootSaga() {
  yield all([
    fork(wathcRequest),
    // ... more watchers will be here...
  ]);
}

Congfigure you store as explained here https://redux-saga.js.org/docs/introduction/BeginnerTutorial.html按照此处的说明配置您的存储https://redux-saga.js.org/docs/introduction/BeginnerTutorial.html

I suggest you to read the documentation more than once.我建议您不止一次阅读文档。 It contains a lot of useful information that at first might be strange but much clearer once you understand how it works.它包含许多有用的信息,起初可能会很奇怪,但一旦您了解它的工作原理,就会清楚得多。

You will need to configure your store to use saga middleware:您需要配置您的商店以使用 saga 中间件:

import React from 'react';
import createSagaMiddleware from 'redux-saga';
import { createStore, applyMiddleware } from 'redux';
import reducer from './reducers';
import rootSaga from './sagas';
const sagaMiddleware = createSagaMiddleware();

const store = createStore(
   reducer,
   applyMiddleware(sagaMiddleware, logger),
);
sagaMiddleware.run(rootSaga); // < -- rootSaga exports all sagas in your app

Then you can convert your thunk to a saga:然后你可以将你的 thunk 转换为一个 saga:

import {call} from 'redux-saga/effects';

function* fetchUsersSaga(payload){
    try {
        yield call(startFetchFun());
        axios.get('https://jsonplaceholder.typicode.com/users')
        .then((response) => {
            yield call(processFetchFun(response.data));
        })
    } catch(err) {
        yield call(endFetchFun(error.message));
        console.log(error.message);
    }
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM