[英]Component rendering too early
我正在尝试创建一个PrivateRoute(HOC)来测试用户是否已经过身份验证(在redux存储中检查'auth'),然后再将它们发送到实际路由。 问题是在我的auth出现在redux商店之前,privateroute完成了。
console.log运行两次,第一次,auth没有出现在商店中,但它第二次,但到那时,它已经将用户路由到登录屏幕....我怎么能给它足够的时间取得完成? 当我只想有条件地显示某些内容时(比如登录/注销按钮),我知道如何处理这种情况,但是当尝试有条件地路由某人时,这种方法也不起作用。
import React, { Component } from 'react'
import { connect } from 'react-redux'
import { Route } from 'react-router-dom'
class PrivateRoute extends Component {
render() {
const { component: Component, ...rest } = this.props
console.log(this.props)
return (
<Route {...rest} render={(props) => (props.auth ? <Component {...props} /> : props.history.push('/login'))} />
)
}
}
function mapStateToProps({ auth }) {
return { auth }
}
export default connect(mapStateToProps)(PrivateRoute)
我没有在这里使用redux
,但我认为你会得到主要观点。 希望这会有所帮助,随时提出任何问题!
import React, { Component } from "react";
import { BrowserRouter, Route, Switch, Redirect } from "react-router-dom";
import Dashboard from "path/to/pages/Dashboard";
class App extends Component {
state = {
isLoggedIn: null,
};
componentDidMount () {
// to survive F5
// when page is refreshed all your in-memory stuff
// is gone
this.setState({ isLoggedIn: !!localStorage.getItem("sessionID") });
}
render () {
return (
<BrowserRouter>
<Switch>
<PrivateRoute
path="/dashboard"
component={Dashboard}
isLoggedIn={this.state.isLoggedIn}
/>
<Route path="/login" component={Login} />
{/* if no url was matched -> goto login page */}
<Redirect to="/login" />
</Switch>
</BrowserRouter>
);
}
}
class PrivateRoute extends Component {
render () {
const { component: Component, isLoggedIn, ...rest } = this.props;
return (
<Route
{...rest}
render={props =>
isLoggedIn ? <Component {...props} /> : <Redirect to="/login" />
}
/>
);
}
}
class Login extends Component {
state = {
login: "",
password: "",
sessionID: null,
};
componentDidMount () {
localStorage.removeItem("sessionID");
}
handleFormSubmit = () => {
fetch({
url: "/my-app/auth",
method: "post",
body: JSON.strigify(this.state),
})
.then(response => response.json())
.then(data => {
localStorage.setItem("sessionID", data.ID);
this.setState({ sessionID: data.ID });
})
.catch(e => {
// error handling stuff
});
};
render () {
const { sessionID } = this.state;
if (sessionID) {
return <Redirect to="/" />;
}
return <div>{/* login form with it's logic */}</div>;
}
}
当您的操作创建者返回令牌时,您需要将其存储在localStorage中。 然后你可以像下面这样创建商店,
const store = createStore(
reducers,
{ auth: { authenticated : localStorage.getItem('token') }},
applyMiddleware(reduxThunk)
)
如果用户已登录,则令牌将在那里。 初始状态将在商店中设置令牌,因此您无需调用任何操作创建者。
现在,您需要通过检查用户是否已登录来保护您的组件。 这是HOC做的,
import React, { Component } from 'react';
import { connect } from 'react-redux';
export default ChildComponent => {
class ComposedComponent extends Component {
componentDidMount() {
this.shouldNavigateAway();
}
componentDidUpdate() {
this.shouldNavigateAway();
}
shouldNavigateAway() {
if (!this.props.auth) {
this.props.history.push('/');
}
}
render() {
return <ChildComponent {...this.props} />;
}
}
function mapStateToProps(state) {
return { auth: state.auth.authenticated };
}
return connect(mapStateToProps)(ComposedComponent);
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.