使用Redux Saga获取数据

时间:2019-12-09 07:50:49

标签: reactjs redux redux-saga

我创建了一个使用redux-thunk从API提取数据的示例。以下代码正在运行。

在这种情况下,我想使用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'));

我想使用redux saga编写上面的代码,以更好地理解sagas。那么,如何在此示例中使用redux-saga?谁能帮助我?

2 个答案:

答案 0 :(得分:1)

Redux Saga使用yield call来调用承诺(如api服务),并使用yield put将操作分派到商店。

区别在于阻止和不阻止呼叫。 因为我们要等待服务器响应我们的请求,所以我们将使用yield call这是一个阻止函数。 使用yield put({ type: "actionName" })而不是直接在生成器内部分派动作。这对于测试目的也很有用。

因此,您应该将自己的传奇写成如下:

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...
  ]);
}

按照此处的说明https://redux-saga.js.org/docs/introduction/BeginnerTutorial.html

存储您的个人资料

我建议您不止一次阅读文档。它包含许多有用的信息,起初可能很奇怪,但是一旦您了解了它的工作原理,就会更加清楚。

答案 1 :(得分:0)

您将需要配置商店以使用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

然后,您可以将thunk转换为传奇:

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);
    }
};