- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在创建我的第一个 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);
演示/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;
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);
}
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/
我的密码 https://gist.github.com/ButuzGOL/707d1605f63eef55e4af 因此,当我收到登录成功回调时,我想进行重定向, 重定向也可以通过调度程序进行。 我
我已经写了访问者模式如下,但我不明白什么是单次和双次分派(dispatch)。AFAIK,单分派(dispatch)是根据调用者类型调用方法,而双分派(dispatch)是根据调用者类型和参数类型调用
我有一个非 ui 线程,我需要在该线程上发送消息。 执行此操作的正常方法是在我的线程的线程过程中调用 Dispatcher.Run()。 我想修改它以使其在处理未处理的异常方面更加健壮。 我的第一个剪
我有一个具有这样功能的代码 const mapDispatchToProps = (dispatch: Dispatch) => ({ onAddProduct: ( key: str
我在使用 Window.Show 显示 WPF 窗口时遇到问题: System.InvalidOperationException was unhandled Message: An unhandle
我对何时使用 Dispatcher.Invoke 从不同线程更新 UI 上的某些内容存有疑问。 这是我的代码... public Window4() { InitializeC
我遇到了一个我无法解决的问题。我正在构建一个电子商务 react 应用程序并使用 useReducer 和 useContext 进行状态管理。客户打开产品,挑选商品数量,然后单击“添加到购物车”按钮
尽管我已经深入了解了 NEventStore 上的事务完整性,但我无法理解在连接了许多 NEventStore 实例时 NEventStore 将如何真正扩展。 总结一下我的理解,一个事件被添加到提交
我学习了 React Javascript 和 Redux,现在我遇到了这个问题。 这是一个 codesandbox 像这样尝试: 搜索书名“dep” 观察日志显示“Search url is:”,当
Dispatcher.CurrentDispatcher(在System.Windows.Threading中)和Application.Current.Dispatcher(在 >系统.Window
我得到了一些代码来处理调度程序在其构造函数中传递给 View 模型的位置。我现在想知道当我想要在 UI 线程上执行某些操作时,我是否应该使用 ObserveOn(dispatcher) 或 dispa
当我们的一个应用程序服务器内存不足时,我正在分析 Java 堆转储。我正在使用 Eclipse 内存分析器。它报告了以下内容。 One instance of "akka.dispatch.Dispa
哪一个: public static let barrier: DispatchWorkItemFlags public static let detached: DispatchWorkItem
我想使用不同于调度类型的类型提示 Action 创建者。 我已经尝试使用这两种类型对 ThunkResult 进行类型提示,但这并不理想。 // types.ts interface AppListA
我正在尝试准确地理解什么是单次分派(dispatch)和多次分派(dispatch)。 我刚刚读到这个: http://en.wikipedia.org/wiki/Multiple_dispatch
I have following api returning Flux of String我有以下返回字符串通量的接口 @GetMapping(value = "/api/getS
这是我自学前端开发一年后在Stackoverflow上的第一个问题。我已经找到了我的疑惑的答案,但由于这些问题是第三次返回,我认为是时候向 Web 提问了。 我正在尝试构建什么 我正在尝试构建一个图书
我正在使用 Kotlin 学习 Android,并且我了解到在不阻塞主线程的情况下启动协程的推荐方法是执行以下操作 MainScope().launch { withContext(Dispatc
错误本身: (alias) deleteCategory(id: number): (dispatch: Dispatch) => void import deleteCategory Argumen
我必须对抽屉进行裁剪,然后创建一个包含所有需要项的DrawerComponent,并创建一个带有NavigationActions的函数来调度我的路线,但是它不起作用。当我单击任何项目时,我都会遇
我是一名优秀的程序员,十分优秀!