浏览器刷新后如何保持 React 组件状态

Posted

技术标签:

【中文标题】浏览器刷新后如何保持 React 组件状态【英文标题】:How to keep React components state after browser refresh 【发布时间】:2016-09-07 15:03:36 【问题描述】:

感谢您阅读我的第一个问题。

我尝试使用共享根进行身份验证,使用 react、react-router 和 firebase。 所以,我想保持 App.js 的用户状态。但是当我尝试刷新浏览器时,没有找到用户状态。

我已尝试保存到本地存储。但是有没有办法在没有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

【问题讨论】:

【参考方案1】:

如果您通过浏览器刷新重新加载页面,您的组件树和状态将重置为初始状态。

要在浏览器中重新加载页面后恢复以前的状态,您必须

在本地保存状态 (localstorage/IndexedDB) 和/或在服务器端重新加载。

并以这样的方式构建您的页面,即在初始化时,检查先前保存的本地状态和/或服务器状态,如果找到,将恢复先前的状态。

【讨论】:

wintvelt,谢谢您的回答。我使用本地存储解决了! @wintvelt 这是一个适当的方法,你不认为这会导致安全原因。 ? @Mr.G 是的,安全(和隐私)是您需要考虑的事情。如果使用 Firebase,则浏览器刷新将再次检查 Firebase 的登录状态,因此 Firebase 将处理这部分安全性。通常,组件 UI 状态,例如打开的页面、打开的下拉菜单、过滤器、复选框、表单中的字段内容(非用户名/密码)等,通常不太敏感,可以存储在本地。就个人而言,我只在本地存储不支持用户登录的状态。并将经过身份验证的用户的状态存储在服务器上(更安全)。

以上是关于浏览器刷新后如何保持 React 组件状态的主要内容,如果未能解决你的问题,请参考以下文章

在 React.JS 中刷新后,如何让用户保持登录到 firebase?

如何在 React.js 中刷新页面后保持状态?

服务器端 Blazor:刷新页面后如何保持用户身份验证?

react-router 如何在页面刷新时保持位置状态?

运行 navigator.pop() 后如何刷新 React 状态?

Vue项目保持用户登录状态(localStorage + vuex 刷新页面后状态依然保持)