我已经浏览了我能找到的用于使用 redux 和 React-router 构建 React 应用程序的所有文档和示例项目,但我似乎无法弄清楚如何在分派操作时更新我的 Redux 状态。正如您在此屏幕截图中看到的,操作正在正确分派,但我的 store/nextState 没有更新。
行动:
export function updateUsername(username) {
return { type: types.UPDATE_USERNAME, username };
}
REDUCER(编辑:我已经尝试过这两种变体):
/* first variation */
const username = (
state = '',
action,
) => {
switch (action.type) {
case types.UPDATE_USERNAME:
return Object.assign({}, state, {
username: action.username,
});
default:
return state;
}
};
/* second variation */
const username = (
state = '',
action,
) => {
switch (action.type) {
case types.UPDATE_USERNAME:
return action.username;
default:
return state;
}
};
减速机组合:
const user = combineReducers({
isAuthenticated,
token,
password,
username,
});
export default user;
减速器/INDEX.JS:
const rootReducer = combineReducers({
isFetching,
open,
search,
user,
routing: routerReducer,
});
export default rootReducer;
店铺配置:
import React from 'react';
import { createStore, compose, applyMiddleware } from 'redux';
import createLogger from 'redux-logger';
import thunkMiddleware from 'redux-thunk';
import { routerMiddleware } from 'react-router-redux';
import rootReducer from '../reducers';
import * as actions from '../actions';
function configureStore(history, initialState) {
const loggerMiddleware = createLogger();
const enhancer = window.__REDUX_DEVTOOLS_EXTENSION__ &&
window.__REDUX_DEVTOOLS_EXTENSION__();
const store = createStore(
rootReducer,
initialState,
compose(
applyMiddleware(
thunkMiddleware,
loggerMiddleware,
routerMiddleware(history),
),
enhancer,
),
);
if (module.hot) {
// Enable Webpack hot module replacement for reducers
module.hot.accept('../reducers', () => {
const nextReducer = rootReducer;
store.replaceReducer(nextReducer);
});
}
return store;
}
export default configureStore;
店铺创建:
const initialState = {};
const store = configureStore(browserHistory, initialState);
const history = syncHistoryWithStore(browserHistory, store);
const routes = createRoutes(store);
render(
<Provider store={store}>
<Router history={history} routes={routes} />
</Provider>,
document.getElementById('root'),
);
最后是组件:
import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import TextField from 'material-ui/TextField';
import validator from 'validator';
import className from 'classnames';
import { Link } from 'react-router';
import * as AuthActions from '../../actions/AuthActions';
class LoginForm extends Component {
constructor(props) {
super(props);
this.handleUsernameChange = this.handleUsernameChange.bind(this);
this.handlePasswordChange = this.handlePasswordChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleUsernameChange(e) {
this.props.actions.updateUsername(validator.escape(e.target.value.trim()));
}
handlePasswordChange(e) {
this.props.actions.updatePassword(validator.escape(e.target.value.trim()));
}
handleSubmit(e, getState) {
e.prevent.default();
const user = { username: this.props.user.username, password: this.props.user.password };
console.log(user);
this.props.actions.loginUser(user);
}
render() {
return (
<form autoComplete="off" onSubmit={this.handleSubmit} className='login-form'>
<TextField
type="username"
autoFocus="true"
floatingLabelText="Username"
floatingLabelFixed={true}
autoComplete="off"
onChange={this.handleUsernameChange}
/>
<br/>
<TextField
type="password"
autoFocus="true"
floatingLabelText="Password"
floatingLabelFixed={true}
autoComplete="off"
onChange={this.handlePasswordChange}
/>
</form>
);
}
}
function mapStateToProps(state) {
return {
user: state.user,
};
}
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators(AuthActions, dispatch),
};
}
export default connect(
mapStateToProps,
mapDispatchToProps,
)(LoginForm);
我已经在这个问题上坚持了一个星期了,所以非常感谢您提供的任何帮助!谢谢!
我还没有运行你的代码,所以我不能立即说这是否可以修复它,但是你的用户名缩减程序正在返回一个具有
username
属性的对象,而它应该返回 action.username
字符串。
const username = (state = '', action) => {
switch (action.type) {
case types.UPDATE_USERNAME:
return action.username
default:
return state;
}
};
此外,您是否已确认您的
types
声明中没有拼写错误?我看到在您的减速器中您引用了 types.UPDATE_USERNAME
,但在您的动作创建器中您使用字符串 UPDATE_USERNAME
设置类型。
就我而言:我有一个从
user
状态获得的 useSelector
对象,然后我更新了用户的角色,它不会识别出它是一个新对象,所以我用 Object.assign({}, user)
复制了该对象,然后触发了dispatch
const user = useSelector((state) => state.user);
user.role = Roles.admin;
dispatch(setUser(Object.assign({}, user)));