简体   繁体   English

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

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

I'm doing a fetch request that makes a new user in my database.我正在做一个获取请求,在我的数据库中创建一个新用户。 All of it works and a new user is made/api-key returned.所有这些都有效,并且创建了一个新用户/返回 api-key。

The problem is that i am unable to pass the received response of my fetch request to my reduces.问题是我无法将我的 fetch 请求的接收响应传递给我的 reduce。 I'm wondering if I should call another action as a response to my successful fetch request that triggers a reducer and takes the response of the request as payload.我想知道是否应该调用另一个操作作为对触发减速器并将请求的响应作为有效负载的成功获取请求的响应。

Or if I am able to pass the response of the fetch request to the reducer instantly.或者,如果我能够立即将获取请求的响应传递给减速器。 Here is my 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)
}

and below is my reducer:下面是我的减速器:

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

when loggin the reducer payload now it says undefined.现在登录减速器有效负载时,它显示未定义。

yield by itself will wait until Promise is resolved if Promise will be returned from the yielded statement.如果 Promise 将从 yielded 语句返回,则yield本身将等到 Promise 被解决。 So correct callAPIregister will be所以正确的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})
}

And also I recommend to consider using call in yield statements.我还建议考虑在yield语句中 使用call It is for easier unit testing这是为了更容易的单元测试

In my opinion, this thing will work for you.在我看来,这件事对你有用。 Made 'FETCH_FAILED' type well if there's any error in fetching then you can catch that error.如果在获取时出现任何错误,则将 'FETCH_FAILED' 类型设置得很好,那么您可以捕获该错误。 So, make one more variable in your reducers initial_state object.因此,在您的减速器 initial_state 对象中再创建一个变量。

sagas.js 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)
}

In your reducer you can create a variable in initial state object and then in your 'REGISTER_SAGA' capture the data that we got from our saga在您的减速器中,您可以在初始状态对象中创建一个变量,然后在您的“REGISTER_SAGA”中捕获我们从我们的传奇中获得的数据

reducer.js减速器.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