Неспособность интегрировать Redux-сагу с Redux - PullRequest
0 голосов
/ 24 октября 2019

Я пытаюсь использовать Redux-saga в первый раз, поэтому у меня есть следующий файл sagas:

backendAuth.js

import {all, call, fork, put, takeEvery} from "redux-saga/effects";
import {auth} from 'backend/backend';
import {
  SIGNIN_USER,
  SIGNOUT_USER,
  SIGNUP_USER
} from "constants/ActionTypes";
import {showAuthMessage, userSignInSuccess, userSignOutSuccess, userSignUpSuccess} from "actions/Auth";

const createUserWithUsernamePasswordRequest = async (username, password) =>
  await  auth.createUserWithUsernameAndPassword(username, password)
    .then(authUser => {
      console.log('authUser: '+authUser);
      return authUser;
    })
    .catch(error => error);

const signInUserWithUsernamePasswordRequest = async (username, password) =>
  await  auth.signInWithUsernameAndPassword(username, password)
    .then(authUser => authUser)
    .catch(error => error);

const signOutRequest = async () =>
  await  auth.signOut()
    .then(authUser => authUser)
    .catch(error => error);

function* createUserWithUsernamePassword({payload}) {
  const {username, email, password} = payload;
  try {
    const signUpUser = yield call(createUserWithUsernamePasswordRequest, username, email, password);
    if (signUpUser.message) {
      yield put(showAuthMessage(signUpUser.message));
    } else {
      localStorage.setItem('user_id', signUpUser.user.uid);
      yield put(userSignUpSuccess(signUpUser.user.uid));
    }
  } catch (error) {
    yield put(showAuthMessage(error));
  }
}

function* signInUserWithUsernamePassword({payload}) {
  const {username, password} = payload;
  try {
    const signInUser = yield call(signInUserWithUsernamePasswordRequest, username, password);
    if (signInUser.message) {
      yield put(showAuthMessage(signInUser.message));
    } else {
      localStorage.setItem('user_id', signInUser.user.uid);
      yield put(userSignInSuccess(signInUser.user.uid));
    }
  } catch (error) {
    yield put(showAuthMessage(error));
  }
}

function* signOut() {
  try {
    const signOutUser = yield call(signOutRequest);
    if (signOutUser === undefined) {
      localStorage.removeItem('user_id');
      yield put(userSignOutSuccess(signOutUser));
    } else {
      yield put(showAuthMessage(signOutUser.message));
    }
  } catch (error) {
    yield put(showAuthMessage(error));
  }
}

export function* createUserAccount() {
  yield takeEvery(SIGNUP_USER, createUserWithUsernamePassword);
}

export function* signInUser() {
  yield takeEvery(SIGNIN_USER, signInUserWithUsernamePassword);
}

export function* signOutUser() {
  yield takeEvery(SIGNOUT_USER, signOut);
}

export default function* rootSaga() {
  yield all([
    fork(signInUser),
    fork(createUserAccount),
    fork(signOutUser)
  ]);
}

И этофайл, в котором выполняется асинхронное обращение к API: backend.js

import axios from 'axios';

const backendServer = 'http://localhost:8000/';

const signInEndpoint = backendServer + 'api/token_auth/';

const signInWithUsernameAndPassword = (username, password) => {
  axios.post(backendServer+"api/token_auth/", {
    username: username,
    password: password
  })
  .then(Response => {
    console.log('Response: '+Response)
    return Response;
  })
  .catch(Error => Error);
}

export const auth = {
  signInWithUsernameAndPassword: signInWithUsernameAndPassword
}

Ajax хорошо выполняется через axios , и достигается console.log() в backend.js, но console.log() в backendAuth нет, и я получаю следующую ошибку в консоли:

index.js:1375 Invariant Violation: Objects are not valid as a React child (found: TypeError: Cannot read property 'then' of undefined). If you meant to render a collection of children, use an array instead.

Я считаю, что проблема заключается в том, как я определяювозврат значения then в ajax backend.js, но я довольно новичок в разработке веб-интерфейса, поэтому я не уверен в этом.

1 Ответ

0 голосов
/ 24 октября 2019

Основная причина - это простое исправление - вы используете явный блок для тела функции signInWithUsernameAndPassword arrow, поэтому вам нужно использовать явный return. Поскольку у вас нет оператора return, функция возвращает undefined, который является каскадным, чтобы вызвать общую проблему.

Быстрое решение состоит в том, чтобы просто обновить функцию до:

const signInWithUsernameAndPassword = (username, password) => {
  return axios.post(backendServer+"api/token_auth/", {
    username: username,
    password: password
  })
  .then(Response => {
    console.log('Response: '+Response)
    return Response;
  })
  .catch(Error => Error);
}

Теперьчтобы понять последнюю ошибку, которую вы видите в данный момент: поскольку signInWithUsernameAndPassword возвращает undefined, вы в конечном итоге вводите блок catch signInWithUsernamePassword в backendAuth.js из-за ошибки типа вызова undefined. затем в signInUserWithUsernamePasswordRequest. Ошибка в этом блоке catch является экземпляром Error, а не простой строкой. Я предполагаю, что вы затем отображаете error, который передается в showAuthError где-то в дереве компонентов реагирования, но экземпляр Error не является чем-то допустимым для визуализации. Вы можете сначала попытаться вызвать toString(), чтобы отобразить будущие ошибки, а не вызывать ошибку рендеринга.

...