繁体   English   中英

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

[英]how to pass returned fetch data to a reducer using redux saga

我正在做一个获取请求,在我的数据库中创建一个新用户。 所有这些都有效,并且创建了一个新用户/返回 api-key。

问题是我无法将我的 fetch 请求的接收响应传递给我的 reduce。 我想知道是否应该调用另一个操作作为对触发减速器并将请求的响应作为有效负载的成功获取请求的响应。

或者,如果我能够立即将获取请求的响应传递给减速器。 这是我的传奇:

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

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

如果 Promise 将从 yielded 语句返回,则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语句中 使用call 这是为了更容易的单元测试

在我看来,这件事对你有用。 如果在获取时出现任何错误,则将 '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”中捕获我们从我们的传奇中获得的数据

减速器.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
        }
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 }));

暂无
暂无

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

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