2016-08-29 15 views
2

React NativeとReduxを使用してアプリケーションを構築していて、実装中に問題が発生しました。React Native/Redux - setState - 既存の状態遷移中に更新できません。

レンダリングや他のコンポーネントのコンストラクタ内で などの既存の状態遷移中にsetStateを更新できません。

私がアプリケーションシミュレータを読み込むと、ユーザ入力の前にhandleLogin()がすぐにトリガされてループ上に表示されるようです。

AuthenticationContainer.js:

はここAuthenticationContainerAuthenticationPageコードです

'use strict' 
 

 
import React, { Component, PropTypes } from 'react'; 
 
import AuthenticatePage from '../../components/Authenticate/AuthenticatePage' 
 
import { connect } from 'react-redux'; 
 
import { bindActionCreators } from 'redux' 
 
import * as sessionActionCreators from '../../redux/session'; 
 
import {Actions, ActionConst} from 'react-native-router-flux' 
 

 
class AuthenticateContainer extends Component { 
 
    constructor(props) { 
 
     super(props); 
 
     this.state = { 
 
      email: '', 
 
      password: '' 
 
     }; 
 
    } 
 

 
    handleLogin() { 
 
     this.props.doLogin(this.state.email, this.state.password) 
 
      .then(() => Actions.tabbar()) 
 
    } 
 

 
    render() { 
 
     return (
 
      <AuthenticatePage 
 
       doLogin = {this.handleLogin.bind(this)} 
 
       error = {this.props.error}/> 
 
     ); 
 
    } 
 
} 
 

 
AuthenticateContainer.propTypes = { 
 
    doLogin: PropTypes.func.isRequired, 
 
    email: PropTypes.string, 
 
    password: PropTypes.string, 
 
    error: PropTypes.string.isRequired 
 
}; 
 

 
export default connect(
 
    (state) => ({isFetching: state.session.isFetching, error: state.session.error}), 
 
    (dispatch) => bindActionCreators(sessionActionCreators, dispatch) 
 
)(AuthenticateContainer)

AuthenticationPage.js

'use strict' 
 

 
import React, { Component, PropTypes } from 'react'; 
 
import {Text, View, TouchableHighlight, AlertIOS} from 'react-native'; 
 
import t from 'tcomb-form-native' 
 
import _ from 'lodash' 
 
import EStyleSheet from 'react-native-extended-stylesheet' 
 
import ViewContainer from '../ViewContainer' 
 

 
// AuthenticatePage.propTypes = { 
 
//  doLogin: PropTypes.func.isRequired, 
 
//  onUpdateForm: PropTypes.func.isRequired, 
 
//  email: PropTypes.string, 
 
//  password: PropTypes.string, 
 
//  error: PropTypes.string.isRequired 
 
// }; 
 

 
var Form = t.form.Form; 
 

 
var User = t.struct({email: t.String, password: t.String}); 
 

 
const options = { 
 
    auto: 'placeholders', 
 
    fields: { 
 
     email: { 
 
      autoCapitalize: 'none', 
 
      autoCorrect: false 
 
     }, 
 

 
     password: { 
 
      autoCapitalize: 'none', 
 
      autoCorrect: false, 
 
      password: true, 
 
      secureTextEntry: true 
 
     } 
 
    } 
 
}; 
 

 
export default class AuthenticatePage extends Component { 
 
    constructor(props) { 
 
     super(props); 
 
     this.state = { 
 
      value: { 
 
       email: '', 
 
       password: '' 
 
      } 
 
     }; 
 
    } 
 

 
    render() { 
 
     return (
 
      <ViewContainer> 
 
       <View> 
 
        <Form 
 
         ref="form" 
 
         type={User} 
 
         options={options} 
 
         value={this.state.value}/> 
 
       </View> 
 
       <View> 
 
        <TouchableHighlight 
 
         onClick={this.props.doLogin()} 
 
         underlayColor='#99d9f4'> 
 
          <Text>{_.capitalize('Login')}</Text> 
 
        </TouchableHighlight> 
 
       </View> 
 
      </ViewContainer> 
 
     ) 
 
    } 
 
}
handleLogin()関数は、ページのロード時に直ちに起動し、エラーをスローしながら繰り返し実行されるようです。シミュレータから受け取ったエラーは次のとおりです。

setState error

任意の助けいただければ幸いです!

+0

プロジェクトでReduxも使用しているときに、状態を直接変更するのはなぜですか? –

+0

こんにちはMaarten、あなたはAuthenticationPage内にあるのですか?フォームからの入力を処理するためにそのコンポーネントの状態を変更しようとしていました。これはどのように達成すべきでしょうか? – Kaidao

+0

ローカル状態を使用してテキストフィールドの値を保存するのは問題ありません。私が理解していないのは、なぜ両方のコンポーネントに電子メールとパスワードがあるのか​​ということです。子コンポーネントでそれを持つだけで、doLoginは関数呼び出しのパラメータとして渡しと電子メールを受け取ります。 –

答えて

6

私はこの問題はここにあると信じて:

onClick={this.props.doLogin()} 

あなたはrender上の関数を呼び出していますが、代わりに小道具として渡す必要があります。どちらか修正する

onClick={() => this.props.doLogin()} 

または

onClick={this.props.doLogin.bind(this)} 

にしてみてください。

+0

ありがとう!これはうまくいった。 – Kaidao

関連する問題