2016-05-12 16 views
3

私の最初の質問をお読みいただきありがとうございます。ブラウザの更新後に反応コンポーネントの状態を維持する方法

私はShared Rootを使って認証しようとしていますが、react、react-router、firebaseを使用しています。 したがって、App.jsのユーザ状態を維持したいと思います。ブラウザを更新しようとすると、ユーザーの状態が見つかりませんでした。

私はlocalstorageに保存しようとしました。しかし、localStorageなしで、ブラウザの更新後にコンポーネントに状態を保持する方法はありますか?


App.js

import React, { Component, PropTypes } from 'react' 
import Rebase from 're-base' 

import auth from './config/auth' 

const base = Rebase.createClass('https://myapp.firebaseio.com') 

export default class App extends Component { 
    constructor (props) { 
    super(props) 
    this.state = { 
     loggedIn: auth.loggedIn(), 
     user: {} 
    } 
    } 

    _updateAuth (loggedIn, user) { 
    this.setState({ 
     loggedIn: !!loggedIn, 
     user: user 
    }) 
    } 

    componentWillMount() { 
    auth.onChange = this._updateAuth.bind(this) 
    auth.login() // save localStorage 
    } 

    render() { 
    return (
     <div> 
     { this.props.children && 
      React.cloneElement(this.props.children, { 
      user: this.state.user 
      }) 
     } 
     </div> 
    ) 
    } 
} 
App.propTypes = { 
    children: PropTypes.any 
} 

auth.js

import Rebase from 're-base' 
const base = Rebase.createClass('https://myapp.firebaseio.com') 

export default { 
    loggedIn() { 
    return !!base.getAuth() 
    }, 

    login (providers, cb) { 
    if (Boolean(base.getAuth())) { 
     this.onChange(true, this.getUser()) 
     return 
    } 

    // I think this is weird... 
    if (!providers) { 
     return 
    } 

    base.authWithOAuthPopup(providers, (err, authData) => { 
     if (err) { 
     console.log('Login Failed!', err) 
     } else { 
     console.log('Authenticated successfully with payload: ', authData) 
     localStorage.setItem('user', JSON.stringify({ 
      name: base.getAuth()[providers].displayName, 
      icon: base.getAuth()[providers].profileImageURL 
     })) 
     this.onChange(true, this.getUser()) 
     if (cb) { cb() } 
     } 
    }) 
    }, 
    logout (cb) { 
    base.unauth() 
    localStorage.clear() 
    this.onChange(false, null) 
    if (cb) { cb() } 
    }, 
    onChange() {}, 
    getUser: function() { return JSON.parse(localStorage.getItem('user')) } 
} 

Login.js

import React, { Component } from 'react' 
import auth from './config/auth.js' 

export default class Login extends Component { 
    constructor (props, context) { 
    super(props) 
    } 

    _login (authType) { 
    auth.login(authType, data => { 
     this.context.router.replace('/authenticated') 
    }) 
    } 
    render() { 
    return (
     <div className='login'> 
     <button onClick={this._login.bind(this, 'twitter')}>Login with Twitter account</button> 
     <button onClick={this._login.bind(this, 'facebook')}>Login with Facebook account</button> 
     </div> 
    ) 
    } 
} 
Login.contextTypes = { 
    router: React.PropTypes.object.isRequired 
} 

答えて

6

ブラウザを更新してページをリロードすると、コンポーネントのツリーと状態が初期状態にリセットされます。ブラウザでページをリロード後に以前の状態に戻すには

、あなたは

  • に持っているローカル(のlocalStorage)
  • および/またはリロードするために、サーバ側での状態を保存します。

初期化時に以前に保存したローカル状態またはサーバー状態をチェックし、見つかった場合は前の状態に戻すようにページを構築します。

+0

wintvelt、ありがとうございます。私はlocalstorageを使って解決しました! – jinma

+0

@wintveltこれはプロッパーのアプローチです、これはセキュリティ上の理由の原因になると思います。 ? –

+2

@ Mr.Gはい、セキュリティ(とプライバシー)はあなたが考慮する必要があるものです。 Firebaseが使用されている場合、ブラウザのリフレッシュはFirebaseでログインした状態を再度チェックします。そのため、Firebaseはセキュリティのその部分を処理します。一般に、どのページが開いているか、どのドロップダウンが開いているか、フィルタ、チェックボックス、フォーム内のフィールドの内容(非ユーザ名/パスワード)などのコンポーネントUI状態は、通常、それほど機密性が低く、ローカルに格納することができます。個人的には、私はユーザーログインの背後にない状態のためにローカルにのみ格納します。また、サーバーに格納する(より安全な)認証されたユーザーに対してのみ状態を保存します。 – wintvelt

関連する問題