您的位置 首页 知识分享

Symfony- React Spa应用程序重新加载问题

问题描述及背景 本文分享一个在Symfony项目中集成React SPA时遇到的页面重新加载问题及解决方案。项…

Symfony- React Spa应用程序重新加载问题

问题描述及背景

本文分享一个在Symfony项目中集成React SPA时遇到的页面重新加载问题及解决方案。项目使用Symfony UX将React前端集成到Symfony应用中,通过Symfony控制器渲染包含主React组件的Twig模板。

Symfony控制器代码:

#[route('/app', name: 'get_app', methods: ['get'])] public function getapp(): Response {     return $this->render('app.html.twig'); }
登录后复制

Twig模板:

<!DOCTYPE html> <html> <head>     <meta charset="utf-8">     <meta content="ie=edge" http-equiv="x-ua-compatible">     <meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name="viewport">     <meta content="" name="description">     <meta content="" name="author">     <title>{% block title %}welcome!{% endblock %}</title>     {% block stylesheets %}         {{ encore_entry_link_tags('app') }}     {% endblock %}     {% block javascripts %}         {{ encore_entry_script_tags('app') }}     {% endblock %} </head> <body>     <div react_component=""></div> </body> </html>
登录后复制

React主组件:

export default function App() {     const wallet = useStellarWallet(walletNetwork.testnet);      return (         <>             <CssBaseline />             <WalletContext.Provider value={{wallet}}>                 <Router>                     <Routes>                         <Route element={<SignIn />} path="/login" />                         <Route children={<Layout />} element={<ProtectedRoute />} path="/app" />                         {/* ... other routes ... */}                     </Routes>                 </Router>             </WalletContext.Provider>         </>     ); }
登录后复制

使用useNavigate钩子进行React SPA导航时,重新加载页面会导致Symfony报错,提示路由不存在。这是因为React路由在前端定义,Symfony路由器无法识别。

初步尝试及局限性

最初尝试在Symfony控制器中添加一个包含slug参数的路由:

#[route('/app', name: 'get_app', methods: ['get'])] #[route('/app/{slug}', name: 'get_app_with_slug', methods: ['get'])] public function getapp(): Response {     return $this->render('app.html.twig'); }
登录后复制

这种方法仅能处理/app/后单个路径段的情况,多段路径(例如/app/project/2/invest)仍然会匹配失败。

最终解决方案

最终解决方案包含前端和后端两部分:

后端(Symfony)修改:

  1. 创建一个内核订阅者,捕获所有以/app/开头的请求:
public static function getSubscribedEvents(): array {     return [         KernelEvents::REQUEST => 'onRequest'     ]; }  public function onRequest(RequestEvent $event): void {     $request = $event->getRequest();     if (preg_match('#^/app/#', $request->getRequestUri())) {         $pathSlug = preg_replace('#^/app/#', '', $request->getRequestUri());         $url = $this->router->generate('get_app', ['qslug' => $pathSlug]);         $event->setResponse(new RedirectResponse($url));     } }
登录后复制
  1. 修改getapp控制器,接收并传递qslug参数到Twig模板:
#[route('/app', name: 'get_app', methods: ['get'])] public function getapp(#[MapQueryParameter] ?string $qslug): Response {     return $this->render('app.html.twig', ['pathSlug' => $qslug]); }
登录后复制
  1. 修改Twig模板,将pathSlug传递给React组件:
<div pathSlug="{{ pathSlug }}" react_component=""></div>
登录后复制

前端(React)修改:

  1. 创建一个自定义钩子useReloadedRoute,用于处理从localStorage中读取和删除重定向路径:
export const useReloadedRoute = (path?: string) => {     // ... (localStorage操作逻辑) ... };
登录后复制
  1. 在React主组件中使用useReloadedRoute,并创建上下文ReloadRouteContext来共享重定向路径:
// ... (React Context 和 App 组件代码,使用 ReloadRouteContext 和 pathSlug prop) ...
登录后复制
  1. 在Layout组件中使用useEffect钩子,检查并处理重定向路径:
const reloadedRoute = useContext(ReloadRouteContext);  useEffect(() => {     const rlRoute = reloadedRoute.getRouteToNavigate();     if (rlRoute) {         const path = '/app/' + rlRoute;         reloadedRoute.removeRouteToNavigate();         navigate(path);     } }, []);
登录后复制

通过以上步骤,实现了在页面重新加载时,将React路由信息传递给后端,再由后端重定向到正确的React路由,从而解决了页面重新加载问题。

总结

此解决方案通过结合Symfony的内核事件监听和React的上下文机制,有效地处理了React SPA在Symfony应用中的页面重新加载问题。 这种方法避免了直接在Symfony中定义React路由,保持了前后端职责分离的原则。

以上就是Symfony- React Spa应用程序重新加载问题的详细内容,更多请关注php中文网其它相关文章!

本文来自网络,不代表甲倪知识立场,转载请注明出处:http://www.spjiani.cn/wp/9189.html

作者: nijia

发表评论

您的电子邮箱地址不会被公开。

联系我们

联系我们

0898-88881688

在线咨询: QQ交谈

邮箱: email@wangzhan.com

工作时间:周一至周五,9:00-17:30,节假日休息

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

关注微博
返回顶部