# 今週何知った? week:20 [](https://hackmd.io/CFlTER5rRHy37AW44sisZw) > [name=ken3ypa] ## Stimulus - Turbo はCRUD処理のSPA化をNo-JSで実現するライブラリだが、こちらは Low-JSでTurboで補いきれない処理を補完する - 状態・イベントハンドラを管理するライブラリ - React などのコンポーネント志向のJSライブラリと違い、DOMの生成までは管理しない - こちらもTurbo 同様、Railsに限らずHTMLを扱うアプリであればフレームワークを選ばず利用できる ## 公式 - https://stimulus.hotwired.dev/ ## 最小構成 ```html <meta charset="utf-8"> <title>Stimulus Test</title> <script src="https://unpkg.com/stimulus/dist/stimulus.umd.js"></script> <script type="module"> const Application = Stimulus.Application const Controller = Stimulus.Controller let app = Application.start() app.register("hello", class extends Controller { static targets = [ "name", "output" ] greet() { this.outputTarget.textContent = `Hello, ${this.nameTarget.value}!` } }) </script> <div data-controller="hello"> <input data-hello-target="name" type="text"> <button data-action="click->hello#greet">Greet</button> <span data-hello-target="output"> </span> </div> ``` ## 主な構成要素 |名前|説明| | --- | --- | |Controller | 状態・イベントハンドラを管理するクラス。StimulusのControllerクラスを継承して定義する。data-controller属性の値とJavaScriptのファイル名が紐づく。Controller内ではJSの記述が可能| |Target | DOM操作対象。data-controller_name-target属性の値とstatic targets = []で定義された値が紐づく | |Action| Controller内のメソッド。data-action属性の値とメソッドが紐づき連動する| ```html <meta charset="utf-8"> <title>Stimulus Test</title> <script src="https://unpkg.com/stimulus/dist/stimulus.umd.js"></script> <script type="module"> const Application = Stimulus.Application const Controller = Stimulus.Controller let app = Application.start() // hello controller を定義 app.register("hello", class extends Controller { // targetとして name, output を指定 static targets = [ "name", "output" ] // greet メソッド hello#greet greet() { // static に定義した target はそれぞれ xxTarget で参照できる this.outputTarget.textContent = `Hello, ${this.nameTarget.value}!` } }) </script> <div data-controller="hello"> // name を target として紐付け <input data-hello-target="name" type="text"> // アクションとイベントを紐付け。click 時に hello#greet を呼び出せるようにする <button data-action="click->hello#greet">Greet</button> // output を target として紐付け <span data-hello-target="output"> </span> </div> ``` あとはこちらを見つつ説明 https://stimulus.hotwired.dev/handbook/introduction > [name=makicamel] ## React で props のバケツリレーを回避する方法 1. コンテクスト (ref [コンテクスト – React](https://ja.reactjs.org/docs/context.html)) 2. コンポーネントコンポジション (ref [コンポジション vs 継承 – React](https://ja.reactjs.org/docs/composition-vs-inheritance.html)) 3. 子コンポーネントをプロパティにする (ref [コンポジション vs 継承#子要素の出力 – React](https://ja.reactjs.org/docs/composition-vs-inheritance.html#containment)) ### コンテクスト - 向いている用途 - 現在のロケール、テーマ、データキャッシュの管理 ```javascript const MyContext = React.createContext(defaultValue); // Provider <MyContext.Provider value={/* 何らかの値 */}> // Consumer <MyContext.Consumer> {value => /* コンテクストの値に基づいて何かをレンダーします */} </MyContext.Consumer> ``` 上記のように Provider に value を渡すと Consumer コンポーネントに渡される ### コンポーネントコンポジション 汎用的なコンポーネントに props を渡して設定することで、より特化したコンポーネントを作成する ```javascript function Dialog(props) { return ( <FancyBorder color="blue"> <h1 className="Dialog-title"> {props.title} </h1> <p className="Dialog-message"> {props.message} </p> </FancyBorder> ); } function WelcomeDialog() { return ( <Dialog title="Welcome" message="Thank you for visiting our spacecraft!" /> ); } ``` ### 子要素の出力 以下のデメリットもある - ツリーの上部に複雑性を持ち込む - ツリーの下部に必要以上の柔軟性を持ち込む ```javascript function Page(props) { const user = props.user; const content = <Feed user={user} />; return ( <PageLayout content={content} /> ); } ```
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up