gpt4 book ai didi

javascript - Dispatch() 调用了一个函数,但是 .then() 在 React-Redux 上不起作用

转载 作者:行者123 更新时间:2023-11-29 21:31:30 25 4
gpt4 key购买 nike

我正在创建我的第一个 React-Redux 应用程序。我正在使用 yo generator-redux并关注此 repo和官方文档。我已经渲染了 de SignIn Presentational Component,它工作正常,如果输入为空白则显示错误。问题出在派送上。我使用 Thunk 中间件,但 repo 没有。

我已经使用 console.log() 来探索我的代码工作的深度,我发现正在调用组件操作,AJAX 请求(使用 axios)工作正常,但是.then()(我认为)不工作但不会抛出错误。

这是我的代码:

行动

actions/UsersActions.js

import axios from 'axios';

//sign in user
export const SIGNIN_USER = 'SIGNIN_USER';
export const SIGNIN_USER_SUCCESS = 'SIGNIN_USER_SUCCESS';
export const SIGNIN_USER_FAILURE = 'SIGNIN_USER_FAILURE';

//Get current user(me) from token in localStorage
export const ME_FROM_TOKEN = 'ME_FROM_TOKEN';
export const ME_FROM_TOKEN_SUCCESS = 'ME_FROM_TOKEN_SUCCESS';
export const ME_FROM_TOKEN_FAILURE = 'ME_FROM_TOKEN_FAILURE';
export const RESET_TOKEN = 'RESET_TOKEN';

//log out user
export const LOGOUT_USER = 'LOGOUT_USER';

axios.defaults.baseURL = location.href.indexOf('10.1.1.33') > 0 ? 'http://10.1.1.33:8080/api/v1' : 'http://10.1.1.33:8080/api/v1';

export function signInUser(formValues) {
const request = axios.post('/login', formValues);
console.log(request);
// It works fine and receives the resposen when is invoked from Container
return {
type: SIGNIN_USER,
payload: request
};
}

export function signInUserSuccess(user) {
return {
type: SIGNIN_USER_SUCCESS,
payload: user
}
}

export function signInUserFailure(error) {
return {
type: SIGNIN_USER_FAILURE,
payload: error
}
}

export function meFromToken(tokenFromStorage) {
//check if the token is still valid, if so, get me from the server
const request = axios.get('/me/from/token?token=${tokenFromStorage}');

return {
type: ME_FROM_TOKEN,
payload: request
};
}

export function meFromTokenSuccess(currentUser) {
return {
type: ME_FROM_TOKEN_SUCCESS,
payload: currentUser
};
}

export function meFromTokenFailure(error) {
return {
type: ME_FROM_TOKEN_FAILURE,
payload: error
};
}


export function resetToken() {//used for logout
return {
type: RESET_TOKEN
};
}

export function logOutUser() {
return {
type: LOGOUT_USER
};
}

组件

components/SignInForm.js

import React, { Component, PropTypes } from 'react';
import { Link } from 'react-router';

class SignInForm extends Component {
static contextTypes = {
router: PropTypes.object
};

componentWillUnmount() {
// Invoked immediately before a component is unmounted from the DOM.
// Perform any necessary cleanup in this method, such as invalidating timers or
// cleaning up any DOM elements that were created in componentDidMount.

// Important! If your component is navigating based on some global state(from say componentWillReceiveProps)
// always reset that global state back to null when you REMOUNT
this.props.resetMe();
}

componentWillReceiveProps(nextProps) {
// Invoked when a component is receiving new props. This method is not called for the initial render.
if(nextProps.user && nextProps.user.status === 'authenticated' && nextProps.user.user && !nextProps.user.error) {
this.context.router.push('/');
}

//error
//Throw error if it was not already thrown (check this.props.user.error to see if alert was already shown)
//If u dont check this.props.user.error, u may throw error multiple times due to redux-form's validation errors
if(nextProps.user && nextProps.user.status === 'signin' && !nextProps.user.user && nextProps.user.error && !this.props.user.error) {
alert(nextProps.user.error.message);
}
}

render() {
const { asyncValidating, fields: { email, password }, handleSubmit, submitting, user } = this.props;

return (
<div>
<form onSubmit={handleSubmit(this.props.signInUser.bind(this))}>
<div>
<label>Email</label>
<input type="text" placeholder="email@4geeks.com.ve" {...email} />
<div>{email.touched ? email.error : ''}</div>
<div>{ asyncValidating === 'email' ? 'validating...' : ''}</div>
</div>
<div>
<label>Password</label>
<input type="password" {...password} />
<div>{password.touched ? password.error : ''}</div>
<div>{ asyncValidating === 'password' ? 'validating...' : ''}</div>
</div>
<button type="submit" disabled={submitting}>Submit</button>
</form>
</div>
);
}
}

export default SignInForm;

容器

容器/SignInFormContainer.js

import { reduxForm } from 'redux-form';
import SignInForm from '../components/SignInForm';
import { signInUser, signInUserSuccess, signInUserFailure } from '../actions/UsersActions';

// Client side validation
function validate(values) {
var errors = {};
var hasErrors = false;
if(!values.email || values.email.trim() == '') {
errors.email = "Enter a registered email.";
hasErrors = true;
}
if(!values.password || values.password.trim() == '') {
errors.password = "Enter password.";
hasErrors = true;
}
return hasErrors && errors;
}

// For any field errors upon submission (i.e. not instant check)
const validateAndSignInUser = (values, dispatch) => {
return new Promise ((resolve, reject) => {
console.log('this is showed');
dispatch(signInUser(values))
.then((response) => {
console.log('this console.log is not showed');
let data = response.payload.data;
// if any one of these exist, then there is a field error
if(response.payload.status != 200) {
// let other components know of error by updating the redux` state
dispatch(signInUserFailure(response.payload));
reject(data); // this is for redux-form itself
} else {
// store JWT Token to browser session storage
// If you use localStorage instead of sessionStorage, then this w/ persisted across tabs and new windows.
// sessionStorage = persisted only in current tab
sessionStorage.setItem('dhfUserToken', response.payload.data.token);
// let other components know that we got user and things are fine by updating the redux` state
dispatch(signInUserSuccess(response.payload));
resolve(); // this is for redux-form itself
}
});
});
}

const mapDispatchToProps = (dispatch) => {
return {
signInUser: validateAndSignInUser
}
}

function mapStateToProps(state, ownProps) {
return {
user: state.user
};
}

// connect: first argument is mapStateToProps, 2nd is mapDispatchToProps
// reduxForm: 1st is form config, 2nd is mapStateToProps, 3rd is mapDispatchToProps
export default reduxForm({
form: 'SignInForm',
fields: ['email', 'password'],
null,
null,
validate

}, mapStateToProps, mapDispatchToProps)(SignInForm);

演示/页面/ View

演示/SignIn.js

import React, { Component } from 'react';
import HeaderContainer from '../containers/HeaderContainer';
import SignInFormContainer from '../containers/SignInFormContainer';

class SignIn extends Component {
render() {
return (
<div>
<HeaderContainer />
<SignInFormContainer />
</div>
);
}
}

export default SignIn;

reducer

reducres/UserReducer.js

import {
ME_FROM_TOKEN, ME_FROM_TOKEN_SUCCESS, ME_FROM_TOKEN_FAILURE, RESET_TOKEN,
SIGNIN_USER, SIGNIN_USER_SUCCESS, SIGNIN_USER_FAILURE,
LOGOUT_USER
} from '../actions/UsersActions';

const INITIAL_STATE = {user: null, status:null, error:null, loading: false};

export default function(state = INITIAL_STATE, action) {
let error;
switch(action.type) {
case ME_FROM_TOKEN:// loading currentUser("me") from jwttoken in local/session storage storage,
return { ...state, user: null, status:'storage', error:null, loading: true};
case ME_FROM_TOKEN_SUCCESS://return user, status = authenticated and make loading = false
return { ...state, user: action.payload.data.user, status:'authenticated', error:null, loading: false}; //<-- authenticated
case ME_FROM_TOKEN_FAILURE:// return error and make loading = false
error = action.payload.data || {message: action.payload.message};//2nd one is network or server down errors
return { ...state, user: null, status:'storage', error:error, loading: false};
case RESET_TOKEN:// remove token from storage make loading = false
return { ...state, user: null, status:'storage', error:null, loading: false};

case SIGNIN_USER:// sign in user, set loading = true and status = signin
return { ...state, user: null, status:'signin', error:null, loading: true};
case SIGNIN_USER_SUCCESS://return authenticated user, make loading = false and status = authenticated
return { ...state, user: action.payload.data.user, status:'authenticated', error:null, loading: false}; //<-- authenticated
case SIGNIN_USER_FAILURE:// return error and make loading = false
error = action.payload.data || {message: action.payload.message};//2nd one is network or server down errors
return { ...state, user: null, status:'signin', error:error, loading: false};

case LOGOUT_USER:
return {...state, user:null, status:'logout', error:null, loading: false};

default:
return state;
}
}

reducers/index.js

import { combineReducers } from 'redux';
import { UserReducer } from './UserReducer';
import { reducer as formReducer } from 'redux-form';

const rootReducer = combineReducers({
user: UserReducer,
form: formReducer // <-- redux-form
});

export default rootReducer;

商店

import {createStore, applyMiddleware, combineReducers, compose} from 'redux';
import thunkMiddleware from 'redux-thunk';
import {devTools, persistState} from 'redux-devtools';
import rootReducer from '../reducers/index';

let createStoreWithMiddleware;

// Configure the dev tools when in DEV mode
if (__DEV__) {
createStoreWithMiddleware = compose(
applyMiddleware(thunkMiddleware),
devTools(),
persistState(window.location.href.match(/[?&]debug_session=([^&]+)\b/))
)(createStore);
} else {
createStoreWithMiddleware = applyMiddleware(thunkMiddleware)(createStore);
}

export default function configureStore(initialState) {
return createStoreWithMiddleware(rootReducer, initialState);
}

索引.js

import React from 'react';
import ReactDOM from 'react-dom';
import {Provider} from 'react-redux';
import { Router, browserHistory } from 'react-router';
import routes from './routes';
import configureStore from './store/configureStore';
import {renderDevTools} from './utils/devTools';

const store = configureStore();

ReactDOM.render(
<div>
{/* <Home /> is your app entry point */}
<Provider store={store}>
<Router history={browserHistory} routes={routes} />
</Provider>

{/* only renders when running in DEV mode */
renderDevTools(store)
}
</div>
, document.getElementById('main'));

希望你能帮帮我!我不知道是否有问题,因为我使用的是 Thunk 而示例没有,或者是否缺少某些内容。

谢谢大家!

最佳答案

看起来您正在使用 redux-thunk,而我正在使用 redux-promise 中间件。他们是完全不同的。如果你想使用 repo,你应该将 redux-thunk 更改为 redux-promise

关于javascript - Dispatch() 调用了一个函数,但是 .then() 在 React-Redux 上不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36230843/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com