我正在使用webpack构建React + Redux + Firebase应用程序,并试图找出处理受保护路由和重定向的最佳方法。我尝试将onEnter()
与setTimeout()
一起使用,就像许多示例所示,但它仍然会在重定向之前闪烁备用组件。
这是我目前拥有的,我正在努力想出一个更优雅的解决方案。这主要是有效的,但它失败的一个例子是我在/profile
并在浏览器中导航到/
。似乎因为firebase.auth()
需要再次初始化,我会在切换到HomePage
之前获得Profile
组件的闪存。
Firebase在firebaseClientConfig
初始化,我将firebase.auth()
传递给routes
。
import { auth } from './firebaseClientConfig';
...
export default (
<Route path="/" component={App}>
<IndexRoute
getComponent={(nextState, cb) => {
auth.onAuthStateChanged((user) => {
if (!user) {
return require.ensure([], require => {
cb(null, require('./components/HomePage').default);
});
} else {
return require.ensure([], require => {
cb(null, require('./modules/Profile/Profile').default);
});
}
});
}}
/>
<Route
path="/profile"
getComponent={(nextState, cb) => {
auth.onAuthStateChanged((user) => {
if (user) {
return require.ensure([], require => {
cb(null, require('./modules/Profile/Profile').default);
});
} else {
return require.ensure([], require => {
cb(null, require('./modules/Login/Login').default);
});
}
});
}}
/>
</Route>
);
有没有人有更好的方法呢?
答案 0 :(得分:1)
我制作了一个PrivateRoute
组件,并传递了一个authenticated
道具,该道具是我在使用PrivateRoute
的组件的redux存储中获得的
当我使用Firebase登录时,我将用户数据存储在redux存储中。所以在我的情况下,我会将状态映射到道具
const mapStateToProps = (state) => ({
authenticated: !!state.user.uid,
})
并将经过身份验证的道具提供给我的PrivateRoute
组件
const PrivateRoute = ({ component: Component, authenticated, path, exact }) => {
return (
<Route
path={path}
exact={exact}
render={props =>
authenticated
? <Component {...props} />
: <Redirect to="/login"/>}
/>
)
}
答案 1 :(得分:0)
如果您使用本地状态而不是redux管理身份验证,则需要创建两个状态来保存身份验证进度。
state={"loading=true",
"loggedin=false"}
即redner在加载为true时以及当我从firebase函数接收当前用户状态时加载组件初始状态时,我将使用setState()将加载设置为flase并进一步根据用户状态渲染我打算渲染的组件。
为更好地理解,请看react firebase authentication
答案 2 :(得分:0)
我知道有点晚了,但是这可能会对其他人有所帮助:您可以找到一种稍微不同的方法here(仍然使用类似于vhflat的私有路由,但是我发现它更加清晰和容易实施)。
基本上,在您的私人路线中,您只是
import { useSelector } from "react-redux";
和
import { isLoaded } from 'react-redux-firebase'
之后,您将获得这样的身份验证
const auth = useSelector( state => state.firebase.auth );
然后,如果isLoaded( auth )
不正确(因此未加载身份验证状态),则可以重定向到加载页面,或者如果不需要的话,只返回<React.Fragment></React.Fragment>
。
最后,如果返回,则可以检查!isEmpty( auth )
是否为真,如果返回true,则返回子组件,否则,重定向到登录页面或您喜欢的任何其他页面。