【问题标题】:Redux thunk function not runningRedux thunk 函数未运行
【发布时间】: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())(请参阅 stackoverflow.com/questions/44334008/…,了解今天早些时候其他人提出的相同问题)。
  • 对不起大家。更新了我的代码。 @markerikson 好电话。我这样做了,但现在得到一个错误,eventstopDefault 函数中未定义??
  • 你没有在&lt;form onSubmit={this.props.dispatch(this.stopDefault())}&gt;中向stopDefault传递任何东西

标签: javascript reactjs redux redux-thunk


【解决方案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
    • 我遇到了类似的问题,我将动作生成器导入到文件中,但忘记使用道具中的调度绑定动作生成器。相反,我直接调用了导入的动作生成器,所以没有任何调度。
    猜你喜欢
    • 2022-01-17
    • 2017-10-31
    • 2020-08-18
    • 2020-12-19
    • 2021-12-11
    • 1970-01-01
    • 2020-03-25
    • 2016-11-23
    • 2018-01-31
    相关资源
    最近更新 更多