2017-01-05 35 views
1

私はreduxとreact-routerの反応アプリを構築するためのドキュメントとサンプルプロジェクトをすべて見てきましたが、アクションをディスパッチするときに私の還元状態を更新する。このスクリーンショットでわかるように、アクションは適切にディスパッチされていますが、私のstore/nextStateは更新されていません。Redux状態がアクションディスパッチで更新されない

enter image description here

ACTION:

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; 

減速/ 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'), 
); 

、そして最後に、COMPONENT:

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

私は今、一週間のために、この上で立ち往生してきたので、あなたが提供できるすべてのヘルプをいただければ幸いです!ありがとう!

+0

これらのコードは正しいですか?あなたはログにUPDATE_USERNAMEを表示しますが、アクションコードはUPDATE_PASSWORDです。 –

+0

良いキャッチです。間違った動作をコピー/貼り付けするだけです。編集されました! – DGaffneyDC

+1

クローンを作成して実行できるようにレポを提供できますか? –

答えて

1

私はあなたのコードを実行していないので、これだけはそれを修正する場合、私はぶっきらぼう言うことはできませんが、それはaction.username文字列を返すべきであるとき、ユーザー名の減速は、usernameプロパティを持つオブジェクトを返しています。また

const username = (state = '', action) => { 
    switch (action.type) { 
    case types.UPDATE_USERNAME: 
     return action.username 
    default: 
     return state; 
    } 
}; 

、あなたがあなたのtypes宣言のタイプミスがないことを確認しましたか?減速機ではtypes.UPDATE_USERNAMEを参照していますが、アクションクリエーターでは文字列UPDATE_USERNAMEを使用してタイプを設定しています。

+0

残念ながら、私は減速機のためのそのフォーマットを試してきました。誰も働いていないようです。限り、型の宣言、私は '*型として'私のレデューサーファイルにインポートしました。私は今それを切り替えようとします。 – DGaffneyDC

+0

'console.log'を' username'リデューサに投げて、それが呼び出されていることを確認しましたか? (または、devtoolsにブレークポイントを追加した) –

+0

うん、それは発砲している。ログインアクションをディスパッチすると、バックエンド認証サービスから200が得られますが、nextStateと同じ問題は更新されません。 – DGaffneyDC

関連する問題