要处理这种特定情况,您可以为您的路由添加 Content Guard(或 Route Guard),专门检查您所需的数据是否存在于 Redux 状态。
你可以在这里使用一个不错的库react-router-guards
或者您始终可以创建自己的逻辑功能组件,以根据您的页面管理您的路由和基本 API 调用
举例
如果您直接访问 hi.com/product/1
1) 当你使用 react-router-guards 时
const requireStates = (to, from, next) => {
if (to.meta.auth) {
if (getIsLoggedIn()) {
let actualPath = to.location.pathname.split("/");
if(actualPath[1] === "product") {
if(isProductAPIDataPresent)// here check if redux state have that particular data present
{
next();
} else {
fetch(); // get Product API data
store(); // store it in redux states
next();
}
} else {
next();
}
}
next.redirect('/login');
} else {
next();
}
};
const App = () => (
<BrowserRouter>
<GuardProvider guards={[requireStates]} loading={Loading} error={NotFound}>
<Switch>
<GuardedRoute path="/product/:productID" exact component={Product} meta={{ auth: true }} />
<GuardedRoute path="/home" exact component={Home} meta={{ auth: true }} />
<GuardedRoute path="/login" component={Login} />
</Switch>
</GuardProvider>
</BrowserRouter>
);
2) 当你想构建自己的功能逻辑时(你可以只做一个功能组件,它会返回一些基本的真假情况)
const requireStates = (tprops) => {
let next = {
isAllowed: true,
newLocation: "/",
}
if (props.meta.auth) {
if (getIsLoggedIn()) {
let actualPath = props.location.pathname.split("/");
if(actualPath[1] === "product") {
if(isProductAPIDataPresent)// here check if redux state have that particular data present
{
return next;
} else {
fetch(); // get Product API data
store(); // store it in redux states
return next;
}
} else {
return next;
}
next.isAllowed = false;
next.newLocation = "/login"
return next;
} else {
return next;
}
};
您还需要制作一个父组件(所有路由通用,它可以是布局组件),它将在继续处理该特定路由组件或子组件之前呈现
所以在那个父组件中,你可以像这样注入上面的逻辑
componentDidMount = async () => {
await requireStates(this.props).then((result) => {
if (!result.isAllowed) {
window.location.replace(result.newLocation);
}
});
};
注意*:对于第二种解决方案,您可以通过多种方式实现所需目标