reactjs - Redux 状态不会随着操作分派(dispatch)而更新

标签 reactjs redux react-router react-redux react-router-redux

我已经浏览了我能找到的所有文档和示例项目,用于使用 Redux 和 React-Router 构建 React 应用程序,但我似乎不知道如何在我使用 Redux 时更新我的​​ Redux 状态 dispatch 行动。正如您在此屏幕截图中看到的,操作正在正确分派(dispatch),但我的 store/nextState 没有更新。

enter image description here

行动:

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;
    }
  };

reducer 组合:

const user = combineReducers({
  isAuthenticated,
  token,
  password,
  username,
});

export default user;

reducer /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 声明中没有拼写错误?我发现在您的 reducer 中您引用了 types.UPDATE_USERNAME,但在您的操作创建器中您使用字符串 UPDATE_USERNAME 设置类型。

关于reactjs - Redux 状态不会随着操作分派(dispatch)而更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41475441/

相关文章:

reactjs - Redux action.type 给出@@redux/INIT

javascript - 如何将 mapStateToProps/redux 添加到 react-navigation TabNavigator?

node.js - 在快速路线上渲染 react 组件

javascript - 如何让 react-native 启用对 JSX(扩展)文件的支持

javascript - 在 react onclick 中循环遍历数组

angular - 效果 "AuthEffects.authLogin$"发送无效操作 : undefined

reactjs - Gatsby.js : Navigating with URL Parameters and the Browser Back/Forward Buttons

javascript - ReactJs - 输入组件从函数返回时表现奇怪

reactjs - 如何使用 react 导航在页面之间传递状态?

javascript - 如何在React.js中制作通用的 'filter'高阶组件?