RTQ_React03 - wahei628/ShareSuke GitHub Wiki
https://www.notion.so/03-helloworld-12ee480a3ecc4a64a58c30605f736797
03_helloworld
🐾 目次
[ app/views/tops/index.html.erb ]
<div class="flex h-[93%] flex-col bg-base-200" id="todo_app"></div>
[ 予想 ] ⇒ id 属性で 指定している
[ app/javascript/react ]
[ app/javascript/react/entrypoints ]
[ app/javascript/react/entrypoints/features ]
app
└-- javascript
└----- react
├----- entrypoints
└----- features
( todo.app.tsx を作成する )
app
└-- javascript
└----- react
├----- entrypoints
│ └----- todo_app.tsx
└----- features
|
todos
└----- index.tsx
コード を 追加
[ app/javascript/react/entrypoints/todo_app.tsx ]
import React from "react";
import { createRoot } from "react-dom/client";
import TodoApp from "../features/todos";
const container = document.getElementById("todo_app");
if (container) {
const root = createRoot(container);
root.render(<TodoApp />);
}
💡
import React from "react"; import { createRoot } from "react-dom/client"; import TodoApp from "../features/todos";
[ import のあとの { 波括弧 } ある or ない 問題 ]
💡 ヒント : エクスポートの方法
Default export
// TodoApp.js export default function TodoApp() { return <div>Todo Application</div>; }↓↓↓↓ import ↓↓↓↓
// 別のファイル import TodoApp from "../features/todos"; // デフォルトエクスポートをインポート
Named export
// utils.js export function add(x, y) { return x + y; } export const PI = 3.14;↓↓↓↓ import ↓↓↓↓
// 別のファイル import { add, PI } from "./utils"; // 名前付きエクスポートをインポート
const container = document.getElementById("todo_app"); if (container) { const root = createRoot(container); root.render(<TodoApp />); }
document.getElementById("todo_app");
⇒ DOM から ID が todo_app の要素を取得 ⇒ containner に格納
root.render
TodoApp コンポーネントをレンダリングする
⇒ TodoApp が指定されたDOM要素内に表示され、マウントできる
React 18 以降:
💡 Udemy の講座との相違点
ReactDOM.createRoot()
という新しい API が導入された。
- ReactDOMというレシーバーの有無
- 変数に格納しているかどうか
- ifで存在を確認しているかどうか
レシーバの有無
⇒ どちらの方式で import するかで 、 レシーバの有無か変わる。
( ReactDOM.createRoot なのか、 createRoot なのか )
import ReactDOM from 'react-dom';import { createRoot } from 'react-dom/client';変数に格納
⇒ コードの再利用性と可読性を高めるための一般的なプラクティス
ifでの存在を確認
⇒ DOM要素が存在するかどうかを確認するのは良い習慣。
該当する要素がない場合に発生するエラーを防ぐ
[ app/javascript/application.js ]
今作ったファイルを読み込むよう記述する
⇒ 相対パス : [ ./react/entrypoints/todo_app" ]
import "@hotwired/turbo-rails";
import "./react/entrypoints/todo_app";
既存のimport "@hotwired/turbo-rails";
を削除しないことで、Rails と Reat の両方が正常に動作する。
index.tsx を作成する
app
└-- javascript
└----- react
├----- entrypoints
│ └----- todo_app.tsx
└----- features
└----- index.tsx
[ app/javascript/react/features/index.tsx ]
import React from "react";
export default function Todos() {
return (
<>
helloworld
</>
);
}
import React from "react";
とあるが、
毎回コンポーネントでこれ書かなきゃいけないの ?? Udemy ではこんなの見なかったんだけど !!!
と思った。
⇒ バージョン17から、毎回記述する必要がなくなったらしい。
ということだったのだが、以下のようにしたら表示されなくなった….
export default function Todos() {
return (
<>
helloworld
</>
);
}
まぁ、大人しく書いておこうっと。
💡 AI 先生に訊いてみたReact 17以上でJSXを使用する際にReact
のインポートが不要になったのは、Babelのプラグイン@babel/plugin-transform-react-jsx
が新しいJSX変換を行うためです。このプラグインが正しく設定されているか確認してください。babel.config.js
または.babelrc
ファイルをチェックし、以下のように設定されている必要があります:
{
"plugins": [
["@babel/plugin-transform-react-jsx", {
"runtime": "automatic"
}]
]
}
"runtime": "automatic"
の設定が重要で、これが新しいJSX変換を有効にします。もし設定がない、または"classic"
になっている場合、古いJS-変換が適用されており、それがReact
のインポートを必要とします。
Webpackを使用している場合、適切なローダーが設定されていることを確誴してください。特にbabel-loader
が正しく構成されている必要があります。webpack.config.js
内の設定を碼き、.js
や.jsx
、.tsx
ファイルに対してbabel-loader
が使用されていることを確認してください。
TypeScriptを使用している場合、tsconfig.json
でjsx
オプションが"react-jsx"
に設定されている必要があります。これにより、TypeScriptコンパイラが新しいJSX変換を行うようになります。設定例は以下の通りです:
{
"compilerOptions": {
"jsx": "react-jsx"
}
}
もし"preserve"
や"react"
に設定されている場合、それが原因でReact
のインポートが必要になる場合があります。
プロジェクトのpackage.json
を確認し、react
とreact-dom
のバージョンが17以上であることを確認してください。また、関連するBabelやTypeScriptのパッケージが最新であるかも確認してください。
これらの設定を確認し、必要に応じて修正することで、import React from "react";
を記述せずともJSXが正しく変換され、コンポーネントが表示されるはずです。もし問題が解決しない場合は、具体的なエラーメッセージや設定ファイルの内容をもう一度確認してみてください。