Redux thunk 函数未运行

Posted

技术标签:

【中文标题】Redux thunk 函数未运行【英文标题】:Redux thunk function not running 【发布时间】:2017-11-04 11:54:20 【问题描述】:

我有一个返回 redux thunk 异步函数的函数。问题是它没有开火。 createUser 函数正在运行,因为它内部的第一个 console.log 语句正在运行,但 redux thunk 函数内部的语句没有运行。我不完全确定为什么?对我可以尝试的事情有什么想法吗?这同样适用于我的 react-native 应用程序,所以不知道为什么它在这里不起作用。

这是createUser 函数。

export function createUser (userData) 

  console.log('Getting here?')

  return function (dispatch, getState) 
    dispatch(authenticating());

    console.log('But are you getting heeeere?')

    const email = userData.email;
    const password = userData.password;

    firebaseAuth.createUserWithEmailAndPassword(email, password).catch((error) => 
      // Handle Errors here.
      var errorCode = error.code;
      var errorMessage = error.message;
      console.log(errorMessage);
    ).then(() => 
      const user = firebaseAuth.currentUser;

      db.ref('/users/' + user.uid).set(
        username: userData.username,
        displayName: userData.displayName,
        uid: user.uid
      )
      dispatch(isAuthed());

    ).catch((error) => 
      console.warn('Error in createUser callback', error)
    );
  

还有我的设置

import React from 'react';
import ReactDOM from 'react-dom';
import  createStore, applyMiddleware, combineReducers  from 'redux';
import  Provider  from 'react-redux';
import thunk from 'redux-thunk';
import  App  from '~/components/App';
import registerServiceWorker from './registerServiceWorker';
import * as reducers from '~/redux';
import './index.css';

const store = createStore(
  combineReducers(reducers),
  applyMiddleware(thunk)
)

ReactDOM.render(
  <Provider store=store>
    <App />
  </Provider>,
  document.getElementById('root'));
registerServiceWorker();

最后,这是我分派的 SignUp 组件。

import React,  Component  from 'react';
import  connect  from 'react-redux';
import PropTypes from 'prop-types';
import  createUser  from '~/redux/modules/authentication';
import './SignUp.css';

class SignUp extends Component 
  static propTypes = 
    dispatch: PropTypes.func.isRequired
  
  constructor(props) 
    super(props);

    this.state = 
      username: '',
      displayName: '',
      email: '',
      password: '',
      confirmPasswordText: ''
    
  
  handleUsernameChange = (event) => 
    this.setState(username: event.target.value);
  
  handleDisplayNameChange = (event) => 
    this.setState(displayName: event.target.value);
  
  handleEmailChange = (event) => 
    this.setState(email: event.target.value);
  
  handlePasswordChange = (event) => 
    this.setState(password: event.target.value);
  
  handleConfirmPasswordChange = (event) => 
    this.setState(confirmPasswordText: event.target.value);
  
  stopDefault = (event) => 
    event.preventDefault();
    createUser(this.state);
  
  render () 
    return (
      <div className="sign-up">
        <div>
          <h1>Nimbus</h1>
        </div>
        <form onSubmit=this.props.dispatch(this.stopDefault())>
          <div className="form-group">
            <label>Username</label>
            <input
              type="text"
              className="sign-up__input form-control"
              id="formGroupExampleInput"
              placeholder="Choose a username"
              onChange=this.handleUsernameChange
            />
          </div>
          <div className="form-group">
            <label>Display Name</label>
            <input
              type="text"
              className="sign-up__input form-control"
              id="formGroupExampleInput2"
              placeholder="Choose a display name"
              onChange=this.handleDisplayNameChange
            />
          </div>
          <div className="form-group">
            <label>Email</label>
            <input
              type="email"
              className="sign-up__input form-control"
              id="formGroupExampleInput3"
              placeholder="Enter your email address"
              onChange=this.handleEmailChange
            />
          </div>
          <div className="form-group">
            <label>Password</label>
            <input
              type="password"
              className="sign-up__input form-control"
              id="formGroupExampleInput4"
              placeholder="Password"
              onChange=this.handlePasswordChange
            />
          </div>
          <div className="form-group">
            <label>Confirm password</label>
            <input
              type="password"
              className="sign-up__input form-control"
              id="formGroupExampleInput4"
              placeholder="Password"
              onChange=this.handleConfirmPasswordChange
            />
          </div>
          <button type="submit" className="sign-up__button btn btn-
primary btn-lg">Sign Up</button>
        </form>
      </div>
    );
  


export default connect()(SignUp);

【问题讨论】:

~ 在您的导入调用中做了什么?这不是标准的事情,如果不知道如何支持它,就很难重现您的问题。 如何调用createUser方法?你使用mapDispatchToProps 还是bindActionCreators?如果您也可以共享这部分代码,那将会很有帮助。 你能显示你在哪里调用这个 thunk 的组件,以及你实际上是如何调用它的吗?最可能的问题是您正在使用 dispatch(createUser),这不起作用 - 它必须是 dispatch(createUser())(请参阅 ***.com/questions/44334008/…,了解今天早些时候其他人提出的相同问题)。 对不起大家。更新了我的代码。 @markerikson 好电话。我这样做了,但现在得到一个错误,eventstopDefault 函数中未定义?? 你没有在&lt;form onSubmit=this.props.dispatch(this.stopDefault())&gt;中向stopDefault传递任何东西 【参考方案1】:

您需要使用从 react-redux 导入的 connect 函数,以使组件可以使用 createUser 函数作为道具,而不是直接使用导入的函数。如果你不这样做,那么你调用的函数没有连接到你的 redux 存储,所以返回的函数(thunky 函数)不会被执行。

import React,  Component  from 'react';
import  connect  from 'react-redux';
import PropTypes from 'prop-types';
import  createUser  from '~/redux/modules/authentication';
import './SignUp.css';

class SignUp extends Component 
    static propTypes 
        createUser: React.PropTypes.func.isRequired
    

    stopDefault = (event) => 
        event.preventDefault();
        this.props.createUser(this.state);
    

    // Rest of component


const mapStateToProps = null;
const mapDispatchToProps = 
    createUser


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

【讨论】:

【参考方案2】:

调用 redux 函数时需要使用dispatch

通过使用 connect 你得到dispatch 作为一个道具,所以你可以调用this.props.dispatch(createUser(this.state))

或者,connect 接受 mapDispatchToProps,就像它说的那样,将调度映射到您传入的道具。

如果您这样做:connect(, createUser ),那么您将有 createUser 可供您使用:this.props.createUser(this.state)

【讨论】:

createUser 运行。这不是问题。 @Geraint 是正确的。您只是在运行createUser 函数,但您必须将其返回值传递给dispatch。因为你实际上并没有发送任何东西,所以什么也没有发生。 @maxwellgover 你是对的,createUser 正在运行,但是从createUser 返回的函数不是,通过使用我在回答中谈到的内容,你最终会调用返回的函数所需的getStatedispatch 我遇到了类似的问题,我将动作生成器导入到文件中,但忘记使用道具中的调度绑定动作生成器。相反,我直接调用了导入的动作生成器,所以没有任何调度。

以上是关于Redux thunk 函数未运行的主要内容,如果未能解决你的问题,请参考以下文章

Redux 中间件未定义

Redux thunk 在下一个操作之前没有解析 + then 不是函数或调度未定义

测试 redux thunk 异步操作给出未定义而不是承诺

无法使用 next-redux-wrapper 让 Redux (Thunks) 与 NextJS 一起工作:未调用 getInitalProps

Redux-Thunk Chaining Actions,得到一个“dispatch(...)然后不是函数错误

在redux和redux thunk中使用异步调度传递参数