使用高阶组件处理经过身份验证的路由时,我遇到了无限循环问题。身份验证非常基本,在redux状态下只是一个true或false的布尔值。
当应用程序最初启动时,它会检查是否有用户存储在localStorage中。如果它不返回null,我们会立即发送一个SIGN_IN操作。
import React from 'react'
import ReactDOM from 'react-dom'
import { HashRouter } from 'react-router-dom'
import { Provider } from 'react-redux'
import { createStore, applyMiddleware } from 'redux'
import reducers from './reducers'
import reduxThunk from 'redux-thunk'
import { SIGN_IN } from './actions/types'
import logger from 'redux-logger'
const createStoreWithMiddleware = applyMiddleware(reduxThunk, logger)(createStore)
const store = createStoreWithMiddleware(reducers)
import App from './components/App'
const user = localStorage.getItem('user')
if(user) {
store.dispatch({ type: SIGN_IN })
}
ReactDOM.render (
<Provider store={store}>
<HashRouter>
<App />
</HashRouter>
</Provider>,
document.querySelector('.main')
)
这是高阶组件。
import React, { Component } from 'react';
import { connect } from 'react-redux';
export default function(ComposedComponent) {
class RequireAuth extends Component {
componentWillMount = () => {
if(!this.props.auth)
this.props.history.push('/')
}
render() {
return <ComposedComponent {...this.props} />
}
}
function mapStateToProps(state) {
return { auth: state.auth };
}
return connect(mapStateToProps)(RequireAuth);
}
componentWillMount中的逻辑似乎是导致无限循环的原因,但我真的不知道为什么。这似乎阻止我去任何其他路线,但正如你在下面的控制台输出中看到的那样,它会以非凡的方式爆发。
如果有帮助,这里是组件,我用HOC包装我的组件。
export default class App extends Component {
constructor(props) {
super(props)
}
render() {
return (
<div className="app"
style={{
backgroundImage: 'url("./img/base-bg.jpg")',
backgroundSize: 'cover',
backgroundPosition: 'center center',
backgroundRepeat: 'no-repeat'
}}
>
<Switch>
<Route path="/" exact component={RequireAuth(Intro)} />
<Route path="/landing" exact component={RequireAuth(Intro)} />
<Route path="/journey" component={RequireAuth(Exhibit)} />
<Redirect to="/landing" />
</Switch>
<Footer />
</div>
)
}
}
如果有帮助,我正在使用React Router V4。为了澄清,包含登录表单和登录页面。如果用户未经过身份验证,则介绍会显示登录表单,并且在初始化时,应显示登录页面。也许这就是我弄乱的地方,不应该嵌套我的组件。我不确定。
答案 0 :(得分:0)
这归结为hackalicious nesting以及我如何使用RequireAuth包装我的组件。我没有在名为Intro的组件中进行登录和着陆,而是取消了该操作并将路由配置更改为:
<Switch>
<Route path="/" exact component={Login} />
<Route path="/landing" exact component={RequireAuth(Landing)} />
</Switch>
现在这是我的HOC,几乎一样。
export default function(ComposedComponent) {
class RequireAuth extends Component {
componentDidMount = () => {
if(!this.props.auth)
this.redirectToLogin()
}
componentWillUpdate = nextProps => {
if(!nextProps.auth)
this.redirectToLogin()
}
redirectToLogin = () => this.props.history.push('/')
render() {
return <ComposedComponent {...this.props} />
}
}
function mapStateToProps(state) {
return { auth: state.auth };
}
return connect(mapStateToProps)(RequireAuth);
}