在解析路由之前获取数据

Fetch data before resolve route

我正在使用路由 "react-router" 库。在渲染页面组件之前,我需要获取数据。我想在每次路由之前显示加载器,因为所有路由都需要来自服务器的数据。我所有的组件都是由控制器驱动的,所以我的解决方案是在所有组件的构造函数中创建这个控制器,并在创建控制器时获取数据。

它有效,但我使用的是打字稿,我想访问数据而无需(!)检查数据。更好的解决方案是使用等待数据并呈现当前页面的包装器组件。对于第一个路由,它可以工作,但是 componentDidMounnt "below in code" 只被调用一次,所以第二个路由不起作用。

<Router>
   <Switch>
     <MyRoute path="/login" component={LoginPage} exact={true} />
     <MyRoute path="/reg" component={RegistrationPage} exact={true} />
   </Switch>
</Router>
/*MyRoute*/
async componentDidMount() {
    try {
            await this.props.routeController.getController(this.props.path).then((controller: PageController) => {
                this.setState({
                    controller: controller
                })
                this.props.routeController.loading = false;
            })
        } catch(err) {
            // error handling
        }
    }

    render() {
        if (!this.props.routeController.loading) {
            const { controller } = this.state; 
            return (
                <this.props.component controller={controller} />
            )
        }

        return <div>LOADING</div>;
    }

所以我需要在路由之前获取数据。之后,我需要在道具中渲染带有数据的页面组件。这个问题有可能还是好的解决方案?如果没有,我该如何解决异步路由问题。谢谢:-)

使状态 isLoading : false, 然后在 componentWiilMount() / DidMount() 中设置 isLoading 状态为真。 获取成功后将 isLoading 重置为 false;

componenetWillMount/didMount(){
this.setState({
isLoading: true
})
fetchData().then(res => this.setState(isLoading: false))
.catch(err => this.setState({isLoading: false}));


render(){
return(
{this.state.isLoading ? <Loader /> : <Component View /> }
)
}

您也可以在切换页面前使用react-router-loading获取数据。

你只需要用 loading 属性标记路由,并告诉路由器何时使用组件中的上下文切换页面:

import { Routes, Route } from "react-router-loading";

<Routes> // or <Switch> for React Router 5
    <Route path="/page1" element={<Page1 />} loading />
    <Route path="/page2" element={<Page2 />} loading />
    ...
</Routes>
// Page1.jsx

import { useLoadingContext } from "react-router-loading";
const loadingContext = useLoadingContext();

const loading = async () => {
    // loading some data

    // call method to indicate that loading is done and we are ready to switch
    loadingContext.done();
};