【问题标题】:Symfony 4 how to setup SPA ( single page app ) with React?Symfony 4 如何使用 React 设置 SPA(单页应用程序)?
【发布时间】:2018-03-01 13:29:38
【问题描述】:

我无法让 Symfony 4 在 SPA 设置中正常工作。

具体来说,当我使用 React-router 链接进行导航时,一切正常。

但是,如果我尝试直接访问任何路由(除了 home ),Symfony 会拦截它,当然,会抛出找不到路由的错误。

将 Symfony 放在子域中并仅将其用作 API 的替代方法是不可行的,因为我需要框架提供的所有用户和会话管理工具。

当然,我需要 Symfony 的路由来处理所有到后端的 API 调用。

我使用 Symfony 4 的默认目录结构,只在顶层为所有 react/redux 代码添加目录 /client。

构建代码放在 /public/build 下。

我还尝试使用以下代码在 /public 上放置一个 .htaccess 文件,但这没有帮助。

Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]

谢谢

【问题讨论】:

  • 这篇文章对你来说可能有点矫枉过正,但可能会给你一些想法。 Symfony React Starter Repo 有趣的东西。
  • 感谢@Cerad,但那篇文章根本没有涉及路由问题。设置单页机不是问题。问题在于 react-router 和 Symfony 的路由器可以很好地协同工作。

标签: php reactjs symfony react-router-dom


【解决方案1】:

可能会有解决方案。

带有路由注解的控制器,无论路由有多少参数,所有路由都会通过这个注解反应来处理:

namespace App\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Routing\Annotation\Route;

class DefaultController extends Controller
{
    /**
     * @Template("default/index.html.twig")
     * @Route("/{reactRouting}", name="index", requirements={"reactRouting"=".+"}, defaults={"reactRouting": null})
     */
    public function index()
    {
        return [];
    }
}

如果您有不应该由 react 处理的路由,您的注释可以排除它们,如下所示 - 所有以 api 开头的路由都不会由 react 处理:

@Route("/{reactRouting}", name="index", requirements={"reactRouting"="^(?!api).+"}, defaults={"reactRouting": null})

Twig 模板,带有根元素:

{% extends 'base.html.twig' %}

{% block stylesheets %}
<link rel="stylesheet" href="{{ asset('build/js/app.css') }}">
{% endblock %}

{% block body %}
    <div id="root"><div>
{% endblock %}

{% block javascripts %}
<script type="text/javascript" src="{{ asset('build/js/app.js') }}"></script>
{% endblock %}

反应索引文件:

import React from 'react';
import ReactDOM from 'react-dom';
import {BrowserRouter, Route, Switch} from 'react-router-dom';

import Home from "./containers/Home";
import AboutUs from "./containers/AboutUs";


ReactDOM.render(
       <BrowserRouter>
            <Switch>
                <Route path="/" component={Home}/>
                <Route path="/about-us" component={AboutUs}/>
            </Switch>
        </BrowserRouter>,
    document.getElementById('root'));

还有我的安可配置:

var Encore = require('@symfony/webpack-encore');

Encore
    // the project directory where compiled assets will be stored
    .setOutputPath('public/build/')
    // the public path used by the web server to access the previous directory
    .setPublicPath('/build')
    .cleanupOutputBeforeBuild()
    .enableSourceMaps(!Encore.isProduction())
    // uncomment to create hashed filenames (e.g. app.abc123.css)
    // .enableVersioning(Encore.isProduction())

    // uncomment to define the assets of the project
    // .addEntry('js/app', './assets/js/app.js')
    // .addStyleEntry('css/app', './assets/css/app.scss')

    // uncomment if you use Sass/SCSS files
    // .enableSassLoader()

    // uncomment for legacy applications that require $/jQuery as a global variable
    // .autoProvidejQuery()

    .enableReactPreset()
    .addEntry('js/app', './react/index.js')
    .configureBabel((config) => {
        config.presets.push('stage-1');
    })
;

module.exports = Encore.getWebpackConfig();

【讨论】:

  • 到目前为止,我下面的解决方案似乎工作正常,所以我坚持下去。还是谢谢。
  • 谢谢。这个解决方案似乎对我很有效。
【解决方案2】:

解决这个问题的正确方法是像这样设置路由注释:

/**
* @Route("/{reactRouting}", name="index", priority="-1", defaults={"reactRouting": null}, requirements={"reactRouting"=".+"})
*/
public function index(): Response
{
    return $this->render('index.html.twig');
}

这里的神奇之处在于使用“priority=-1”参数。这允许 symfony 使用路由来找到 API 方法的正确路径,并且只有在没有找到路由时,React 路由器才会启动,寻找它的路由。如果也没有 React 路由,你应该使用 React 应用程序中的一些“NotFound”组件来处理它。

通过这种方法,您仍然可以使用 SPA,但还可以在同一个应用中定义所有逻辑并使用 API。

【讨论】:

    【解决方案3】:

    我相信我找到了可能的设置。

    在 Symfony 的 routes.yaml 中包含 react-router 路由,它们都指向生成 React 根组件的同一个控制器。

    所有其他路由,例如 API 调用,都将正常设置。

    //config/routes.yaml
    //all routes handled by PWA(react-router) pointing to same controller
    home:
       path: /
       controller: App\Controller\IndexController::index
    
    account:
       path: /account
       controller: App\Controller\IndexController::index
    

    如果有人知道替代设置,请分享。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-07-31
      • 2018-06-23
      • 1970-01-01
      • 1970-01-01
      • 2015-06-02
      • 1970-01-01
      • 2014-07-10
      相关资源
      最近更新 更多