Реакция-Редукция. Функция действия вызывается, но объекты внутри инструкции return не обрабатываются

#javascript #reactjs #redux #react-redux

Вопрос:

Я играю, создавая страницу входа в систему, и в настоящее время я сталкиваюсь со странной проблемой, используя redux и thunk со следующим кодом.

войдите в систему.tsx:

 import React from "react";
import { connect } from "react-redux";
import "./Common.css";
import {authentications} from "redux/actions/userActions";

interface Props {
  login: (username: string, password: string) => any,
  logout: () => void,
}

interface State {
  username: string,
  password: string,
  submitted: boolean,
}

class LoginComponent extends React.Component<Props, State> {
  constructor(props: Props) {
    super(props);

    this.state = {
        username: '',
        password: '',
        submitted: false,
    };

    this.setUsername = this.setUsername.bind(this);
    this.setPassword = this.setPassword.bind(this);
    this.submitHandler = this.submitHandler.bind(this);
  }

  setUsername(e: any) {
    const { value } = e.target;
    this.setState({ username: value });
  }

  setPassword(e: any) {
    const { value } = e.target;
    this.setState({ password: value });
  }

  async submitHandler(event: React.SyntheticEvent) {
    event.preventDefault();

    const { username, password } = this.state;
    if (username amp;amp; password) {
      console.log('call login function in login page');
      this.props.login(username, password);
    }
  };

  render() {
    const { username, password} = this.state;
    return (
      <div>
        <section>
          <h2>authentication</h2>
          <form method="post" onSubmit={this.submitHandler}>
            <div>
              <input
                name="username"
                value={username}
                type="text"
                placeholder="name"
                className="TextField"
                onChange={this.setUsername}
              />
              <input
                name="password"
                value={password}
                type="password"
                placeholder="password"
                className="TextField"
                onChange={this.setPassword}
              />
            </div>
            <button type="submit" className="SubmitButton">submit</button>
          </form>
        </section>
      </div>
    );
  }
}

function mapStateToProps (state: State) {
  const {username} = state;
  return {
    username: username,
  }
}

function mapDispatchToProps () {
  return {
    login: authentications.login,
    logout: authentications.logout,
  }
}

const Login = connect(mapStateToProps, mapDispatchToProps)(LoginComponent);
export {Login as LoginComponent}
 

UserAction.tsx

 import { userConstants } from 'redux/CONSTANTS';
import { userServices } from 'services/index';

export const authentications = {
    login,
    logout,
};

function login(username: string, password: string) {
    console.log("within the login function");
    return (dispatch: any) => {
        console.log('within dispatch function'); // this part is not called
        dispatch(request(username));
        userServices.login(username, password)
            .then(
                username => { 
                    dispatch(success(username.toString()));
                    // history.push('/');
                },
                error => {
                    dispatch(failure(username, error.toString()));
                    // dispatch(alertActions.error(error.toString()));
                }
            );
    };

    function request(username: string) { console.log('file request'); return { type: userConstants.LOGIN_REQUEST, username } }
    function success(username: string) { console.log('success'); return { type: userConstants.LOGIN_SUCCESS, username } }
    function failure(username: string, error: string) { console.log('failure'); return { type: userConstants.LOGIN_FAILURE, username, error } }
}

function logout() {
    userServices.logout();
    return { type: userConstants.LOGOUT };
}
 

Проблема в том, что ничего после оператора return в функции входа в систему не вызывается.

Я поискал на веб-сайте и не нашел никакой подобной проблемы. Поэтому мне было интересно, в чем может быть причина.

Ответ №1:

Вы mapDispatchToProps должны быть либо «длинной» версией, фактически вызывающей dispatch , как в другом ответе (но это обычно необходимо, только если вы хотите добавить логику вручную), либо просто объектом. Эта версия стенографии объекта является рекомендуемой версией в настоящее время:

 const mapDispatchToProps = {
    login: authentications.login,
    logout: authentications.logout,
}
 

Комментарии:

1. Ты тот самый мужчина! Действительно ценю вашу помощь.

Ответ №2:

Вы не переходите dispatch в mapDispatchToProps , вот пример из off docs:

 const increment = () => ({ type: 'INCREMENT' })
const decrement = () => ({ type: 'DECREMENT' })
const reset = () => ({ type: 'RESET' })

const mapDispatchToProps = (dispatch) => {
  return {
    // dispatching actions returned by action creators
    increment: () => dispatch(increment()),
    decrement: () => dispatch(decrement()),
    reset: () => dispatch(reset()),
  }
} 

UPD: как упоминал @phry, вы также можете вернуть только объект. что рекомендуется:

 const mapDispatchToProps = {
    login: authentications.login,
    logout: authentications.logout,
}
 

Комментарии:

1. Кроме того, если вы еще этого не знали, есть объектная стенография, которая избавляет от части этого кода и рекомендуется для большинства применений — см. Мой ответ 🙂

2. Большое вам спасибо за помощь!