登录时反应刷新组件

时间:2019-05-17 18:54:43

标签: javascript reactjs

我有2个组件,NavBar,其中包含登录模式和页面的“正文”。 我想检测用户何时登录并基于此重新呈现页面。使用第一个组件的模式登录时,如何在第二个组件中更新登录道具?

简化代码的简短形式:

// NavBar.js

export default class NavBar extends Component {
  constructor(props) {
    super(props)
    this.initialState = {
      username: "",
      password: "",
      loginModal: false
    }
    this.handleLogin = this.handleLogin.bind(this)
 }
 handleLogin(e) { 
  e.preventDefault()
  loginAPI.then(result)
 }

 render() {
 return( <nav> nav bar with links and login button </nav>)
}

//一些随机页面

export default class Checkout extends Component {
  constructor(props) {
    super(props);
    this.state = {
      order_type: 'none',
      loggedIn: false
    }
    this.Auth = new AuthService()
  }
  componentDidMount() {
    if (this.Auth.loggedIn()) {
      const { username, email } = this.Auth.getProfile()
      this.setState({ loggedIn: true, email: email })
    }
    try {
      const { order_type } = this.props.location.state[0]
      if (order_type) {
        this.setState({ order_type: order_type })
      }
    } catch (error) {
      console.log('No package selected')
    }
  }

  componentDidUpdate(prevProps, prevState) {
    console.log("this.props, prevState)
    if (this.props.loggedIn !== prevProps.loggedIn) {
      console.log('foo bar')
    }
  }

  render() {
    return (
      <section id='checkout'>

          User is {this.state.loggedIn ? 'Looged in' : 'logged out'}

      </section>
    )
  }
}

// App.js

function App() {
  return (
    <div>
      <NavBar />
      <Routes /> // This contains routes.js
      <Footer />
    </div>
  );
}

// routes.js

const Routes = () => (
  <Switch>
    <Route exact path="/" component={Home} />
    <Route exact path="/register" component={Register} />
    <Route exact path="/registersuccess" component={RegisterSuccess} />
    <Route exact path="/faq" component={FAQ} />
    <Route exact path="/checkout" component={Checkout} />
    <Route exact path="/contact" component={Contact} />
    {/* <PrivateRoute exact path="/dashboard" component={Dashboard} /> */}
    <Route path="/(notfound|[\s\S]*)/" component={NotFound} />
  </Switch>
)

1 个答案:

答案 0 :(得分:1)

我建议使用react context API存储有关已登录用户的信息。

请参阅:https://reactjs.org/docs/context.html

示例

auth-context.js

import React from 'react'

const AuthContext = React.createContext(null);

export default AuthContext

index.js

import React, { useState } from 'react'
import ReactDOM from 'react-dom'
import App from './App'
import AuthContext from './auth-context.js'

const AppWrapper = () => {
  const [loggedIn, setLoggedIn] = useState(false)

  return (
    <AuthContext.Provider value={{ loggedIn, setLoggedIn }}>
      <App />
    </AuthContext.Provider>
  )
}

ReactDOM.render(
  <AppWrapper/>,
  document.querySelector('#app')
)

然后,您可以在任何组件内部导入AuthContext并使用Consumer组件检查用户是否已登录,以便设置登录状态。

NavBar.js

import React from 'react'
import AuthContext from './auth-context.js'

const NavBar = () => (
  <AuthContext.Consumer>
    {({ loggedIn, setLoggedIn }) => (
      <>
        <h1>{loggedIn ? 'Welcome' : 'Log in'}</h1>

        {!loggedIn && (
          <button onClick={() => setLoggedIn(true)}>Login</button>
        )}
      </>
    )}
  </AuthContext.Consumer>
)

export default NavBar

HOC版本

with-auth-props.js

import React from 'react'
import AuthContext from './auth-context'

const withAuthProps = (Component) => {
  return (props) => (
    <AuthContext.Consumer>
      {({ loggedIn, setLoggedIn }) => (
        <Component
          loggedIn={loggedIn}
          setLoggedIn={setLoggedIn}
          {...props}
        />
      )}
    </AuthContext.Consumer>
  )
}

export default withAuthProps

TestComponent.js

import React from 'react'
import withAuthProps from './with-auth-props'

const TestComponent = ({ loggedIn, setLoggedIn }) => (
  <div>
    <h1>{loggedIn ? 'Welcome' : 'Log in'}</h1>

    {!loggedIn && (
      <button onClick={() => setLoggedIn(true)}>Login</button>
    )}
  </div>
)

export default withAuthProps(TestComponent)

或者,如果您使用react-redux进行了Redux设置,则它将在后台使用上下文API。因此,您可以使用connect HOC将登录状态包装到任何组件道具。