Действие Redux работает, а редуктор - нет - PullRequest
0 голосов
/ 29 июня 2018

Не уверен, почему мой редуктор не работает. У меня есть файл console.log в моем файле действий. Так, например, когда я тестирую неудачную попытку входа в систему, я вижу консольный журнал как в функции loginFromAPI, так и в функции loginFailure (см. В actions.js ниже) . Они выводят то, что ожидается. Но по какой-то причине редуктор входа не работает. Когда я в console.log в loginReducer.js , я ничего не вижу. Это говорит мне, что хотя действие работает, редуктор - нет. Мой редукторный реквизит не меняется из исходного состояния (я проверил это, выведя на консоль). Буду признателен за любую помощь в решении этой проблемы.

Вот структура файла:

app
   reducers
      loginReducer.js
      rootReducer.js
   screens
      Login
         Login.js
         index.js
         actions.js
   store
      configureStore.js
App.js
actionTypes.js

Файл configureStore.js

import { createStore, applyMiddleware } from 'redux';
import app from '../reducers/rootReducer';
import thunk from 'redux-thunk';
import {createLogger} from 'redux-logger';

export default function configureStore() {
    const logger = createLogger();
    let store = createStore(app, applyMiddleware(thunk, logger));
    return store;
}

Файл rootReducer.js

import { combineReducers } from 'redux';
import loginReducer, * as fromLogin from './loginReducer';

export default combineReducers({
    login: loginReducer
})

export const getLogin = (state) => fromLogin.getLogin(state.login)

Файл loginReducer.js

import { LOGIN, LOGIN_SUCCESS, LOGIN_FAILURE } from '../actionTypes';


const initialState = {
    user: {},
    isFetching: false,
    isLoggedIn: false,
    error: false,
    errorMessage: "",
}

export default function loginReducer(state = initialState, action) {
    console.log(action); <-- I do not see this
    switch(action.type) {
        case LOGIN:
            return {
                ...state,
                isFetching: true,
                user: {}
            }
        case LOGIN_SUCCESS: 
            return {
                ...state, 
                isFetching: false,
                isLoggedIn: true,
                user: action.user
            }
        case LOGIN_FAILURE:
            return {
                isFetching: false,
                error: true,
                errorMessage: action.errorMessage
            }
        default:
            return state
    }
}

export const getLogin = (state) => ({
    user: state.user,
    isFetching: state.isFetching,
    isLoggedIn: state.isLoggedIn,
    error: state.error,
    errorMessage: state.errorMessage
})

Файл actions.js

import { LOGIN, LOGIN_SUCCESS, LOGIN_FAILURE } from '../../actionTypes';
import axios from 'axios';

export function loginFromAPI(loginInfo) {
        login();
        axios({
            method: 'POST',
            url: 'SOME_URL_GOES_HERE',
            headers: {
                'Content-Type': 'application/json; charset=utf-8',
            },
            data: JSON.stringify({
                email: loginInfo.email,
                password: loginInfo.password
            }),  
        })
        .then((response) => {
            loginSuccess(response.data);
            console.log(response.data);
        })
        .catch(error => {
            switch(error.response.status) {
                case 404:
                    console.log("No user with that email.");
                    loginFailure("No user with that email.")
                    break;
                case 401: 
                    console.log("Invalid password.");
                    loginFailure("Invalid password.")
                    break;
                default: 
                    console.log("There was an error loggin in");
                    loginFailure("There was an error loggin in");
                    break;
            }

        })

}

function login() {
    return {
        type: LOGIN,
    }
}

function loginSuccess(user) {
    return {
        type: LOGIN_SUCCESS,
        user
    }
}

function loginFailure(errorMessage) {
    console.log(errorMessage); <-- I see this output
    return {
        type: LOGIN_FAILURE,
        errorMessage
    }
}

Файл index.js

import Login from './Login';
import {connect} from 'react-redux';
import * as actions from './actions';
import {getLogin} from '../../reducers/rootReducer';

const mapStateToProps = (state) => ({
    ...getLogin(state),
})

const mapDispatchToProps = () => ({
    ...actions
})

export default connect(mapStateToProps, mapDispatchToProps)(Login)

Файл Login.js

export default class Login extends Component {

  constructor(props) {
    super(props);

    this.state = {
      email: null,
      password: null,
    }
    this.login = this.login.bind(this);
  }

  login() {
    this.props.loginFromAPI({email: this.state.email, password: this.state.password});
    console.log(this.props) <-- This never changes but does show up
  }

  render() {
    let error = this.props.error

    return (
      <ImageBackground source={require('../../assets/Signup.png')} style={styles.container}>
        <View style={styles.content}>

          ...

          Some text input Stuff

          ...

          {error && 
              <Text>{this.props.errorMessage}</Text>
          }

            <Button     
              onPress={this.login}
            />

          ...

    );
  }
}

Ответы [ 2 ]

0 голосов
/ 29 июня 2018

Таким образом, чтобы действие сработало, вам необходимо вернуть объект, содержащий ключ «type», соответствующий вашему случаю переключения редуктора.

{ тип: "MY_ACTION_TYPE" }

Однако ваша функция loginFromAPI является асинхронной, и поэтому вы не можете просто вернуть объект из нее. Чтобы обойти это, вы можете использовать промежуточное программное обеспечение Redux.

Двумя наиболее популярными являются redux-thunk и redux-saga. Избыточный толчок намного проще.

Пример Thunk:

export function loginFromAPI(loginInfo) {
 return function (dispatch) {
   dispatch(login())

   login()
     .then(res => dispatch(loginSuccess()) // the action you want to dispatch
 }
}

https://www.npmjs.com/package/redux-thunk

https://github.com/redux-saga/redux-saga

0 голосов
/ 29 июня 2018

Вы не отправляете свое действие в mapDispatchToProps. https://redux.js.org/basics/actions

...