2017-09-20 11 views
3

主にチケットを確認するためのReact Nativeアプリを、イベント管理者が使用するために構築しています。バックエンドは、機能するOAuth2サーバーを備えたLaravelアプリケーションによって提供されます。私はそのサーバーに対して実際にログインしていますが、アクセストークンを格納したり、イベントなどのデータを要求したり、チケットが特定のイベントと一致するかどうかを確認する必要があります。Reduxに値を保存する

私はアクセストークンなどを保存するためにReduxを実装しようとしています。私が持っているログインフォームは、アクションを使ってストアを正しく更新しますが、アクセストークンで動作するようにはできません。ここで

は、ログイン画面である:

import React, { Component } from 'react'; 
import { Text, View, TextInput, Button } from 'react-native'; 
import { connect } from 'react-redux' 
import StringifyBody from './../lib/oauth2/StringifyBody' 
import { login, storeTokens } from '../redux/actions/auth.js' 

class Login extends Component { 
    constructor (props) { 
     super(props); 
     this.state = { 
      route: 'Login', 
      loading: false, 
      email: '', 
      password: '', 
      accessToken: '', 
     }; 
    } 

    handleClick (e) { 
    e.preventDefault(); 

    return new Promise(function(resolve, reject) { 
    var data = StringifyBody(this.state.password, this.state.email) 

     // XHR settings 
     var xhr = new XMLHttpRequest() 
     xhr.withCredentials = true 

     xhr.onerror = function() { 
      reject(Error('There was a network error.')) 
     } 

     xhr.open("POST", "http://192.168.0.141/oauth/access_token") 
     xhr.setRequestHeader("content-type", "application/x-www-form-urlencoded") 

     xhr.send(data) 

     xhr.onloadend = function() { 

      if (xhr.status === 200) { 

       var parsedJson = JSON.parse(xhr.response) 

       responseArray = [] 

       for(var i in parsedJson) { 
        responseArray.push([parsedJson [i]]) 
       } 

       // assign values to appropriate variables 
       let accessToken = responseArray[0]; 

       console.log('access token is: ' + accessToken) 

       accessToken => this.setState({ access_token: accessToken }) 

       this.props.tokenStore(this.state.accessToken) // This doesn't work: "cannot read property 'tokenStore' of undefined" 

       resolve(xhr.response) 

      } else { 
       reject(Error('Whoops! something went wrong. Error: ' + xhr.statusText)) 
      } 
     } 
    }) 
    .done(() => { 
     this.props.onLogin(this.state.email, this.state.password); // This works 
    }) 
} 
    render() { 

    return (
     <View style={{padding: 20}}> 
      <Text style={{fontSize: 27}}>{this.state.route}</Text> 
      <TextInput 
       placeholder='Email' 
       autoCapitalize='none' 
       autoCorrect={false} 
       keyboardType='email-address' 
       value={this.state.email} 
       onChangeText={(value) => this.setState({ email: value })} /> 
      <TextInput 
       placeholder='Password' 
       autoCapitalize='none' 
       autoCorrect={false} 
       secureTextEntry={true} 
       value={this.state.password} 
       onChangeText={(value) => this.setState({ password: value })} /> 
      <View style={{margin: 7}}/> 
      <Button onPress={(e) => this.handleClick(e)} title={this.state.route}/> 
     </View> 
    ); 
} 
} 

const mapStateToProps = state => { 
    return { 
    isLoggedIn: state.auth.isLoggedIn, 
    access_token: state.auth.access_token, 
    } 
} 

const mapDispatchToProps = (dispatch) => { 
    return { 
    onLogin: (email, password) => { dispatch(login(email, password)); }, 
    tokenStore: (accessToken) => { dispatch(storeTokens(accessToken)) }, 
    } 
} 

export default connect(mapStateToProps, mapDispatchToProps)(Login); 

Reduxのアクション:

export const login = (email, password) => { 
    return { 
    type: 'LOGIN', 
    email: email, 
    password: password 
    }; 
}; 

export const logout =() => { 
    return { 
    type: 'LOGOUT' 
    }; 
}; 

export const storeTokens =() => { 
    return { 
    type: 'STORE_TOKENS', 
    access_token: accessToken, 
    } 
} 

そして最後に減速:

const defaultState = { 
    isLoggedIn: false, 
    email: '', 
    password: '', 
    access_token: '', 
}; 

export default function reducer(state = defaultState, action) { 
    switch (action.type) { 
    case 'LOGIN': 
     return Object.assign({}, state, { 
      isLoggedIn: true, 
      email: action.email, 
      password: action.password 
     }); 
    case 'LOGOUT': 
     return Object.assign({}, state, { 
      isLoggedIn: false, 
      email: '', 
      password: '' 
     }); 
    case 'STORE_TOKENS': 
     return Object.assign({}, state, { 
      access_token: action.accessToken, 
     }) 
    default: 
     return state; 
    } 
} 

私もthis.props.storeTokensにデータを渡す試してみました(実際のアクション)componentDidMount()で私にエラーを与える

私の質問は次のとおりです。私はXHR POSTから得た変数をレフィックスストアにどのように保存するのですか? this.props.tokenStorethis.props.storeTokenが定義されていないのはなぜですか?

+0

私は専門家ではありませんが、私が持っていたいくつかの実装から、私のレデューサーの名前が付けられました。あなたの場合、それはauthという名前になります。あなたはconsole.log this.props、何を得るのですか? –

+0

@Gaëllan私はget:Object {isLoggedIn:false、access_token: ""、login:function、storeTokens:function、logout:function} (私はLogin.jsのディスパッチをアクションに移しました。 ) –

+0

accessTokenはstoreTokensのどこから来たのですか?私はそれが定義されて表示されません。 –

答えて

3

こんにちは、JavaScriptのコンセプトによるミスです。 this.props.tokenStore(this..state.accessToken)//これは機能しません: "未定義のtokenStore 'プロパティを読み取ることができません"

関数内にES5構文を定義しました。関数の外にある参照を変数に格納し、その代わりにその変数を使用するかのどちらかです。もう1つのオプションは、代わりに矢印関数を定義することです。したがって、機能キーワードを ()=> に変更してください。これはうまくいくはずです。これは現在の実装では、あなたが考えているコンポーネントを指していません

+0

ありがとう!これはそれだった。 私が解決したフォローアップの問題がありました。私は 'access_token:accessToken'と言っていましたが、' accessToken:accessToken'だったはずです。私はアクションが鍵を求めていたと思っていました。戻り値の変数ではありません。いずれにせよ、ありがとう、レッスンは私の構文を知るために(再び)学んだ。 –

関連する問題