Redux动作分发无效。

5
我正在尝试在用户提交表单时派发一个动作。假设我有一个提交按钮,触发表单上的onSubmit事件(最终将显示旋转图标,表示表单请求正在处理中,但此时,提交按钮只显示一个truefalse值,表示是否显示旋转图标)。 LoginPage.js
import React from 'react';
import { Link } from 'react-router-dom';

export class LoginPage extends React.Component {
  constructor(props) {
    super(props);
    this.handleLogin = this.handleLogin.bind(this);
  }

  handleLogin(e) {
    e.preventDefault();
    let email = document.getElementById('userEmail').value;
    let password = document.getElementById('userPassword').value;
    this.props.loginHandler(email, password);
  }

  render() {
    return (
      <form onSubmit={ this.handleLogin }>
        <input type="submit" value={ this.props.requestingLogin } />
      </form>
    );
  }
}

export default LoginPage;

LoginPageContainer.js

import React from 'react';
import { connect } from 'react-redux';
import LoginPage from '../../components/login/LoginPage';
import { loginUser } from '../../actions';

export class LoginPageContainer extends React.Component {
    constructor(props) {
        super(props);
    }

    render() {
        return (
            <LoginPage requestingLogin={ this.props.requestingLogin } loginHandler={ this.props.loginUser } />
        );
    }
}

const mapStateToProps = state => {
    const { loginUserReducer } = state;
    return {
        requestingLogin: loginUserReducer.isRequestingLogin,
    };
};

const mapDispatchToProps = dispatch => {
    return {
        loginUser: (email, password) => { 
            dispatch(loginUser(email, password));
        }
    }
};


export default connect(mapStateToProps,  mapDispatchToProps)(LoginPageContainer);

actions/目录下的index.js

export const REQUEST_LOGIN = 'REQUEST_LOGIN';
function requestLogin() {
  return {
    type: REQUEST_LOGIN,
  };
};

export const loginUser = (email, password) => {
    return dispatch => {
        // this works because when the button is clicked,
        // I can successfully console log in here.
        dispatch(requestLogin); // THIS DISPATCH IS NOT WORKING
        // API call here...
    }
};

reducers/中的index.js

import { combineReducers } from 'redux';
import { REQUEST_LOGIN } from '../actions';

const initialLoginState = {
    isRequestingLogin: false,
};

function loginUserReducer(state = initialLoginState, action) {
    switch(action.type) {
        case REQUEST_LOGIN:
            return Object.assign({}, state, { isRequestingLogin: true });
        default:
            console.log('returned from default');
            return state;
    }
}

const allReducers = combineReducers({
    loginUserReducer,
});

export default allReducers;

奇怪的是,我在loginUser()内部执行dispatch()后的API调用有效,但dispatch()本身却无效。

我看过许多在线教程,我的代码与我看到的相符,但出于某种原因,我无法弄清派发操作为什么不起作用。非常感谢您提供任何帮助。


点击“提交”按钮后,您的页面是否重新加载? - Panther
不,我在handleLogin()方法中有e.preventDefault();,但是我忘记在问题中加上了。 - Ol' Reliable
5
你只需要将 dispatch(requestLogin); 改为 dispatch(requestLogin());,并可能将所需的数据传递给动作。 - Panther
@Panther,这样做让它工作了!非常感谢!你能否创建一个答案? - Ol' Reliable
@Ol' Reliable 遇到了同样的问题。有什么解决建议吗? - Vikas Gupta
@Vikash.777 正如 @Panther 所提到的,正确的方法是将 dispatch(requestLogin); 更改为 dispatch(requestLogin(email, password);。如果仍然无法正常工作,请告诉我。 - Ol' Reliable
1个回答

8
问题出在这里:
const mapDispatchToProps = dispatch => {
    return {
        loginUser: (email, password) => { 
            dispatch(loginUser(email, password)); [DISPATCH ACTION]
        }
    }
};

所以loginUser是一个函数,它接受电子邮件、密码,并调用dispatch(loginUser(email, password))。

但是loginUser(email, password)并不返回一个操作,而是返回一个函数。

export const loginUser = (email, password) => {
     return dispatch => {
         // this works because when the button is clicked,
         // I can successfully console log in here.
         dispatch(requestLogin); // THIS DISPATCH IS NOT WORKING
         // API call here...
      }
};

因此,[DISPATCH ACTION]这条线路不会派发一个动作,而是会派发一个函数。

要使它正确,您可以进行以下更改:

const mapDispatchToProps = dispatch => {
    return {
        loginUser: (email, password) => {
             loginUser(email, password)(dispatch);
        }
    }
};

所以,loginUser返回一个函数,你需要将dispatch作为参数调用它。但这看起来并不美观。如何正确地做呢?

export const loginUser = dispatch => {
    return (email, password) => {
        // this works because when the button is clicked,
        // I can successfully console log in here.
        dispatch(requestLogin()); // THIS DISPATCH IS NOT WORKING
        // API call here...
    }
};

在mapDispatchToProps中:

const mapDispatchToProps = dispatch => {
    return {
        loginUser: loginUser(dispatch)
    }
};

我尝试了这个,但仍然不起作用,没有错误,但行为与之前完全相同(API可以通过,但调度未起作用)。 - Ol' Reliable
是的,我忘记了。 - Daniel Tran
现在它能工作了吗?我也有同样的问题,但是还没有解决。 - Arepalli Praveenkumar
@ArepalliPraveenkumar 哈哈,三年后来问它是否仍在运行。 - NewUser134

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接