このマニュアルはphp7.0のみに対応したものです。php7.1以上ではreactjs.htmlをご覧ください。
Redux UIチュートリアル
このチュートリアルではTwigテンプレートエンジン等の代わりにV8JsとRudux-ReactJsを使ってHTMLレンダリングします。 マルチエントリーの非SPAアプリケーションを主な対象としていてJavaScriptではルーターは使用していません。
既存のテンプレートエンジンを使ったWebアプリケーションから、ページ単位でRedux React UIを使ったアプリケーションに移行することができます。
前提条件
- php7.0
- V8Js
- node
- yarn
インストール
BEAR.Sundayプロジェクトを作成します。
composer create-project bear/skeleton MyVendor.MyRedux
vendor名をMyVendor
にproject名をMyRedux
として入力します。
次にBEAR.ReactJsModule
をインストールします。
cd MyVendor.MyRedux
composer require bear/reactjs-module ~0.3
Reduxのスケルトンアプリをインストールします。
cp -r vendor/bear/reactjs-module/ui-skeleton/redux/ui .
cp vendor/bear/reactjs-module/ui-skeleton/redux/package.json .
yarn install
Redux UIの作成
example
からcpしてhello
ページを作成します。
cp -r ui/src/page/example ui/src/page/hello
ui/entry.js
を変更します。
module.exports = {
react: 'src/react-bundle.js',
ssr_hello: 'src/page/hello/app/server',
hello: [
'webpack/hot/dev-server',
'webpack-hot-middleware/client',
'src/page/hello/app/client',
],
};
lintやtest、buildを試してみましょう。(必須ではありません)
yarn run lint
yarn run test
^C
yarn run build
src/Module/AppModule.php
にモジュールをインストールします。
<?php
namespace MyVendor\MyRedux\Module;
use BEAR\Package\PackageModule;
use BEAR\ReactJsModule\ReduxModule;
use BEAR\Package\AbstractAppModule;
use josegonzalez\Dotenv\Loader as Dotenv;
class AppModule extends AbstractAppModule
{
/**
* {@inheritdoc}
*/
protected function configure()
{
//configure()に追加
$distDir = dirname(__DIR__, 2) . '/var/www/dist';
$this->install(new ReduxModule($distDir, 'ssr_hello'));
$this->install(new PackageModule);
}
}
リソースの作成
既存のsrc/Resource/Page/Index.php
を変更します。リソースオブジェクトのレンダラーをRedux UIにするためにsetRenderer
セッターインジェクションに@Inject
と@Named
をアノテートします。@Named
の値はReduxModule
で指定したJSアプリケーションの名前と同じにします。
<?php
namespace MyVendor\MyRedux\Resource\Page;
use BEAR\Resource\RenderInterface;
use BEAR\Resource\ResourceObject;
use Ray\Di\Di\Inject;
use Ray\Di\Di\Named;
class Index extends ResourceObject
{
/**
* @Inject
* @Named("ssr_hello")
*/
public function setRenderer(RenderInterface $renderer)
{
parent::setRenderer($renderer);
}
public function onGet($name = 'BEAR.Sunday')
{
$this->body = [
'title' => 'To ' . $name,
'hello' => ['message' => 'Hello ' . $name]
];
return $this;
}
}
テンプレートの作成
リソースのテンプレートsrc/Resource/Page/Index.html.php
を作成します。
<?php
/* @var $ssr BEAR\ReactJsModule\Ssr */
list($markup, $script) = $ssr->render(['hello']);
return <<<"EOT"
<!doctype>
<html>
<head>
<title>{$ssr->escape('title')}</title>
</head>
<body>
<div id="root">{$markup}</div>
<script src="build/react.bundle.js"></script>
<script src="build/hello.bundle.js"></script>
<script>{$script}</script>
</body>
</html>
EOT;
リソースオブジェクトからpreloadedState
として使う値のキーだけを指定してrender()
します。上記リソースからページのタイトルにtitle
、ReduxのpreloadedStateにhello
を使用します。
実行
start
コマンドを実行するとwebpackが実行され127.0.0.1:8080
でWebサーバーが実行されます。
yarn run start
開発用にdev
コマンドを実行するとphpcs
/phpmd
監視やHMR、browserSyncの機能と共にstart
が実行されます。 注) HMRはpure functionのコンポーネントには対応していないようです。
yarn run dev
デバック
- Chromeプラグイン React developer tools、Redux devToolsが利用できます。
{"title":"To BEAR.Sunday","message":"Hello BEAR.Sunday"}
などとJSONが出力された場合はレンダラーのインジェクションが行われていなくて、Json Rendererが使用されています。Unexpected key "{key}" found in preloadedState
の例外は存在しないResouceObject::$bodyのキーを指定していることを示しています。- 500エラーが帰ってくる場合は
var/log
やcurl
にアクセスしてレスポンス詳細を見てみましょう
このチュートリアルで作成したアプリケーションはMyVendor.MyReduxで参照できます。