设置本地存储后立即更新站点

时间:2020-05-19 21:28:45

标签: reactjs mern

我正在制作一个现代堆栈应用程序,当前我正在尝试在登录路径和主页之间进行切换,这取决于您是否登录。但是,这仅在刷新页面后才起作用,是否有任何方法可以使它工作而不必刷新页面?

App.js

  {!localStorage.getItem('token') ? (
         <Redirect exact from='/' to='/login' />
      ): 
      <>
      <Navbar />
      <Redirect to='/' />


      </>
      }

1 个答案:

答案 0 :(得分:0)

对本地存储的更改做出反应-最好-是一种怪异的方法。实际上,重新渲染组件的唯一方法是通过其接收的更改道具,或通过useState使用组件状态。

我将编写这段虚构的代码来说明我的观点:

import React, { useState } from 'react'
import { useHistory } from 'react-router-dom'

// ...

const LoginPage = _props {
  const [token, setToken] = useState(localStorage.getItem('token'))

  if (token) {
    return <Redirect to='/' />
  }

  // I have no idea how you login your users
  return (
    <div>
      <LoginForm onToken={setToken} />
    </div>
  )
}

如果您需要组件A对组件B所做的更改作出反应,而这两个更改都不是另一个的直接子代,则需要全局状态

全局状态类似于组件状态,因为对它的更改应触发依赖于它的组件的重新渲染。但这是 global ,而不是特定组件的本地。

要实现这一点,可以使用类似redux的复杂解决方案,但是您可以使用React Context实现一个非常简单的版本:

// src/providers/GlobalStateProvider.js
import React, { createContext, useContext, useState } from 'react'

const Context = createContext()

const GlobalStateProvider = ({ children }) => {
  const [token, doSetToken] = useState(localStorage.getItem('token'))

  const setToken = t => {
    doSetToken(t)
    localStorage.setItem('token', token)
  }

  return (
    <Context.Provider value={{ token, setToken }}>
      {children}
    </Context>
  )
}

export { Context }
export default GlobalStateProvider

// src/App.js
import GlobalStateProvider from './providers/GlobalStateProvider'
// ...
const App = _props => {
  return (
    {/* Any component that is descendant of this one can access the context values, an will re-render if they change */}
    <GlobalStateProvider>
      {/* ... the rest of your components */}
    </GlobalStateProvider>
  )
}
// ...

// your particular component
import React, { useContext } from 'react'
import { Context } from 'path/to/GlobalStateProvider'

const SomeComponent = _props => {
  // Component will re-render if token changes
  // you can change token from wherever by using `setToken`
  const { token, setToken } = useContext(Context)

  if (token) {
    // do this
  } else {
    // do that
  }
}