0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Reactの感覚でThymeleafを書いたらちょっと違った話

Last updated at Posted at 2025-07-09

はじめに

Reactに慣れていて、Thymeleafでモーダルを共通化しようとしたら「モーダルの中身(content/children)が二重で表示される」現象でちょっと違うなと思いました。Thymeleafの特徴の後に、fragmentをpropsやchildrenみたいに渡して使うときの注意点をまとめます。

前提知識

HTMLをサーバーサイドで構築する。
「再利用」を利用するためにfragmentblock等を使う。
React のような動的UIとは違い、基本は静的HTMLとして出力されるため、扱いには注意する。

fragment

イメージ

再利用可能なHTML部品(≒ コンポーネント定義)

子コンポーネント

fragments/card.html
<div th:fragment="userCard(name)">
  <div class="card">
    <p th:text="${name}"></p>
  </div>
</div>

親コンポーネント(呼び出し)

<div th:replace="fragments/card :: userCard(${user.name})"></div>

出力イメージ

<!-- <div th:fragment="userCard(name)"> の<div>は表示されない -->
<div class="card"> 
  <p>田中</p>
</div>

複数propsもどきの扱い

子コンポーネント

fragments/card.html
<div th:fragment="userCard(name)">
  <div class="card">
    <p th:text="${name}"></p>
  </div>
</div>

親コンポーネント

<div
  th:replace="fragments/card :: userCard(
                name=${user.name},
                age=${user.age},
                role='admin')"></div>

※下記でも可能だが、上記の方がわかりやすい。

<div th:replace="fragments/card :: userCard(${user.name}, ${user.age}, ${user.role})"></div>

insert

イメージ

呼び出し元のタグの中に、fragmentを子として表示する。

子コンポーネント

fragments/info.htm
<div th:fragment="infoBox">
  <p>お知らせ:メンテナンス予定あり</p>
</div>

親コンポーネント

<section th:insert="fragments/info :: infoBox"></section>

出力イメージ

<section>
  <div>
    <p>お知らせ:メンテナンス予定あり</p>
  </div>
</section>

下記のタグは残って、その中の子要素になる。
<section th:insert="fragments/info :: infoBox"></section>

--- 今日はここまで 近日中に追記する ---

repalce

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?