如何使用redux saga将返回的获取数据传递给reducer

时间:2019-12-02 08:37:53

标签: reactjs react-native redux redux-saga

我正在执行获取请求,该请求在数据库中产生了一个新用户。所有这些都起作用,并且使新用户/返回了api-key。

问题是我无法将收到的提取请求响应传递给我的reduces。 我想知道是否应该调用另一个操作作为对成功获取请求的响应,该请求触发了reducer并将请求的响应作为有效负载。

或者如果我能够立即将获取请求的响应传递给reducer。 这是我的SAGA:

import { call, put, takeEvery, takeLatest, delay } from 'redux-saga/effects';
import {REGISTER} from '../redux/actions/loginAPIcall'

function* callAPIregister(){ 
    const json = yield fetch('http://spotlight-api.local/api/register', {
        method: 'POST',
        headers: {
          Accept: 'application/json',
         'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          name: 'apptest3',
          email: 'apptest3@test.be',
          password: '123456789'
        }),
      })
      .then((response) => response.json())
              .then(data => {
                  console.log(data)
              })
    yield put({type: 'REGISTER_SAGA', payload: json})
}

export function* watchAPIcall(){
    yield takeEvery(REGISTER, callAPIregister)
}

以下是我的减速器:

import {REGISTER, LOGIN} from '../actions/loginAPIcall'

const initialState = {
    apiCalling: false, 
    occupation: null
}

function addAPIcall(state = initialState, action, payload){
    console.log('inside the api reducer')
    switch(action.type){
        case "REGISTER_SAGA":
            console.log('inside register_saga reducer', payload)
            return {
                apiCalling: true,
                occupation: 'REGISTER'
                }
        case LOGIN:
            return {
                apiCalling: true,
                occupation: 'LOGIN'
            }
        default:
            return state;
            }
}
export default addAPIcall

现在登录减速器有效负载时,它表示未定义。

3 个答案:

答案 0 :(得分:1)

如果从yielded语句返回Promise,则

yield本身将等待直到Promise被解决。所以正确的callAPIregister

function* callAPIregister(){ 
    // yield will wait for Promise to resolve
    const response = yield fetch('http://spotlight-api.local/api/register', {
        method: 'POST',
        headers: {
          Accept: 'application/json',
         'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          name: 'apptest3',
          email: 'apptest3@test.be',
          password: '123456789'
        }),
      })
    // Again yield will wait for Promise to resolve
    const data = yield response.json()
    console.log(data)
    yield put({type: 'REGISTER_SAGA', payload: data})
}

我还建议在yield语句中考虑using call。这是为了简化单元测试

答案 1 :(得分:0)

我认为,这件事对您有用。如果在读取时出现任何错误,则使“ FETCH_FAILED”类型正确,然后即可捕获该错误。因此,在化简器的initial_state对象中再添加一个变量。

sagas.js

import { call, put, takeLatest, takeEvery } from 'redux-saga/effects';
import {REGISTER} from '../redux/actions/loginAPIcall';

function getData(payload){
    return fetch('http://spotlight-api.local/api/register', {
        method: 'POST',
        headers: {
            Accept: 'application/json',
            'Content-Type': 'application/json',
        },
        body: JSON.stringify(payload),
    })
    .then(response => response.json())
    .then(json => json)
    .catch(error => {
      throw error;
    });
}

function* callAPIregister(){ 
  try{
    const payload = {
      name: 'apptest3',
      email: 'apptest3@test.be',
      password: '123456789'
    }
    const response = yield call(getData, payload);

    //In this please check what is the name of your data variable
    //Eg if its message then you can
    console.log(response);
    //use response: response.message
    yield put({type: 'REGISTER_SAGA', response: response})
  } catch (error){
    yield put({ type: 'FETCH_FAILED', error });
  }
}

export function* watchAPIcall(){
    yield takeEvery(REGISTER, callAPIregister)
}

在化简器中,您可以在初始状态对象中创建一个变量,然后在“ REGISTER_SAGA”中捕获我们从传奇中获得的数据

reducer.js

const initialState = {
    apiCalling: false, 
    occupation: null,
    data: []
}

case "REGISTER_SAGA":
        console.log('inside register_saga reducer', payload)
        return {
            apiCalling: true,
            occupation: 'REGISTER',
            data: action.response
        }

答案 2 :(得分:0)

import { takeEvery, put, call } from "redux-saga/effects";   
import { AnyAction } from "redux";

const users = [
    {
      id: 1,
      name: "Keshav Gera",
      email: "Keshav.Gera@gmail.com"
    },
    {
      id: 2,
      name: "Happy Gera",
      email: "Happy.Gera@gmail.com"
    }
  ];
  yield put(getUsersSuccess({ users }));