如何在浏览器刷新后保持 React 组件状态 [英] How to keep React components state after browser refresh

查看:54
本文介绍了如何在浏览器刷新后保持 React 组件状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

我尝试保存到本地存储.但是有没有办法在没有 localStorage 的情况下在浏览器刷新后保持组件的状态?

<小时>

App.js

import React, { Component, PropTypes } from 'react'从're-base'导入Rebase从./config/auth"导入身份验证const base = Rebase.createClass('https://myapp.firebaseio.com')导出默认类 App 扩展组件 {构造函数(道具){超级(道具)this.state = {登录:auth.loggedIn(),用户:{}}}_updateAuth(登录,用户){this.setState({登录:!!登录,用户:用户})}组件WillMount(){auth.onChange = this._updateAuth.bind(this)auth.login()//保存 localStorage}使成为 () {返回 (<div>{ this.props.children &&React.cloneElement(this.props.children, {用户:this.state.user})}

)}}App.propTypes = {儿童:PropTypes.any}

auth.js

从're-base'导入Rebaseconst base = Rebase.createClass('https://myapp.firebaseio.com')导出默认{登录 () {返回 !!base.getAuth()},登录(提供商,CB){如果(布尔(base.getAuth())){this.onChange(true, this.getUser())返回}//我觉得这很奇怪...如果(!提供者){返回}base.authWithOAuthPopup(providers, (err, authData) => {如果(错误){console.log('登录失败!', err)} 别的 {console.log('验证成功,有效负载:', authData)localStorage.setItem('user', JSON.stringify({名称:base.getAuth()[providers].displayName,图标:base.getAuth()[providers].profileImageURL}))this.onChange(true, this.getUser())如果 (cb) { cb() }}})},注销 (cb) {base.unauth()localStorage.clear()this.onChange(false, null)如果 (cb) { cb() }},onChange(){},getUser: function () { return JSON.parse(localStorage.getItem('user')) }}

Login.js

import React, { Component } from 'react'从./config/auth.js"导入身份验证导出默认类登录扩展组件{构造函数(道具,上下文){超级(道具)}_登录(身份验证类型){auth.login(authType, 数据 => {this.context.router.replace('/认证')})}使成为 () {返回 (

<button onClick={this._login.bind(this, 'twitter')}>使用推特账号登录</button><button onClick={this._login.bind(this, 'facebook')}>使用 Facebook 帐户登录</button>

)}}Login.contextTypes = {路由器:React.PropTypes.object.isRequired}

解决方案

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

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

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

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

Thank you reading my first question.

I trying to auth With Shared Root use react, react-router and firebase. So, I want to keep App.js 's user state. but when I tried to refresh the browser, user state was not found.

I've tried to save to localstorage. But is there a way to keep state on component after browser refresh without 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
}

解决方案

If you reload the page through a browser refresh, your component tree and state will reset to initial state.

To restore a previous state after a page reload in browser, you have to

  • save state locally (localstorage/IndexedDB)
  • and/ or at server side to reload.

And build your page in such a way that on initialisation, a check is made for previously saved local state and/or server state, and if found, the previous state will be restored.

这篇关于如何在浏览器刷新后保持 React 组件状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆