質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.44%
React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

2回答

957閲覧

【React】useStateフックで管理されていない関数が引数をとって関数のように振る舞うことができるのはなぜでしょうか?

echizeyayota

総合スコア106

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

1クリップ

投稿2023/07/17 07:53

以下の質問についてご存知の方がいらっしゃればご教示を願います。

【質問の主旨】

モーダル画面で任意の言語をコードを選ぶとその言語コードを保持した状態で、ホーム画面に戻るアプリを作成しました。

この機能が実行できる理由は、Modal.jsのsselectタグのonChnageプロパティhandleSelectedChange関数が代入されているからです。

さらにhandleSelectedChange関数を詳しく見るとは、setChosenLanguagesetShowModalの2行で構成されています。

ただsetChosenLanguageは、App.jsにおいてuseStateフックで定義されているsetShowModalと異なり、Modal.jsやApp.jsでuseStateや関数の定義がされていません。

にもかかわらずなぜsetChosenLanguageは、引数e.target.valueを取って関数のように振る舞うことができるのでしょうか?

【質問の補足】

1. Modal.js

const Modal = ({ setShowModal, chosenLanguage, setChosenLanguage }) => { const handleSelectedChange = (e) => { setChosenLanguage(e.target.value); setShowModal(null); } return ( <div className="option-list"> <div className="search-bar"> <select className="source-language" value={chosenLanguage} onChange={handleSelectedChange} > <option value="BG">Bulgarian</option> <option value="CS">Czech</option> <option value="DA">Danish</option> <option value="DE">German</option> <option value="EL">Greek</option> <option value="EN">English</option> <option value="ES">Spanish</option> <option value="ET">Estonian</option> <option value="FI">Finnish</option> <option value="FR">French</option> <option value="HU">Hungarian</option> <option value="ID">Indonesian</option> <option value="IT">Italian</option> <option value="JA">Japanese</option> <option value="KO">Korean</option> <option value="LT">Lithuanian</option> <option value="LV">Latvian</option> <option value="NB">Norwegian Bokmål</option> <option value="NL">Dutch</option> <option value="PL">Polish</option> <option value="PT">Portuguese</option> <option value="RO">Romanian</option> <option value="RU">Russian</option> <option value="SK">Slovak</option> <option value="SL">Slovenian</option> <option value="SV">Swedish</option> <option value="TR">Turkish</option> <option value="UK">Ukrainian</option> <option value="ZH">Chinese</option> </select> <div className="close-button" onClick={() => setShowModal(null)}> <svg focusable="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" > <path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"></path> </svg> </div> </div> </div> ) } export default Modal;

2. App.js

import TextBox from "./components/TextBox"; import Arrows from "./components/Arrows"; import Button from "./components/Button"; import Modal from "./components/Modal"; import { useState } from "react"; const App = () => { const [showModal, setShowModal] = useState(null); const [inputLanguage, setInputLanguage] = useState("English"); const [outputLanguage, setOutputLanguage] = useState("Japanese"); const handleClick = () => { setInputLanguage(outputLanguage); setOutputLanguage(inputLanguage); } console.log("showModal", showModal); return ( <div className="app"> {!showModal && <> <TextBox selectedLanguage={inputLanguage} style='input' setShowModal={setShowModal} /> <div className="arrow-container" onClick={handleClick}> <Arrows /> </div> <TextBox selectedLanguage={outputLanguage} style='output' setShowModal={setShowModal} /> </>} {showModal && <Modal setShowModal={setShowModal} chosenLanguage={showModal === "input" ? inputLanguage : outputLanguage} setChosenLanguage={showModal === "input" ? setInputLanguage : setOutputLanguage} />} </div> ); } export default App;

3. その他のコード

Modal.jsとApp.js以外のコードについてはGitHubリポジトリに保存しています。

4. コードの参考としたページ

Modal.jsのコードは、先日teratailの質問で教えていただいた内容に基づいています。この質問から回答を得たときは、setChosenLanguageの振る舞いについてそれほど気になっていませんでしたが、コードを再度確認しているうちに今回の質問をするようになりました。


以上、ご確認よろしくお願い申し上げます。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

失礼します。質問者様は「変数・引数・プロパティ」と「そこに入っているオブジェクト(関数もオブジェクトの一部です)」を混同されているように見受けられます。

  • JavaScript では、関数は第一級オブジェクトである
  • 変数にはオブジェクト(の参照)を代入されている
  • 関数に引数としてオブジェクトを渡すとはどういうことか

という JavaScript の変数・関数オブジェクトの基礎的理解

  • <SomeComponent /> という書き方は JSX 記法ということ。
  • <SomeComponent onHoge={() => { console.log("hoge") }}/>と書くと、 SomeComponent は引数として { onHoge: /* 上記の「"hoge" とコンソールに出力する」関数オブジェクト */ } というオブジェクトを受け取っている

という、React の JSX 記法についての基礎的な理解が必要なので、もし上記の説明が理解できないなら、そこから確認されることをオススメします。

JSX において「Props を渡す」が、どのような仕組みなのか分かる公式ドキュメントの記事を添付しておきます。このサイトは重要なエッセンスが詰まっているので、ブックマーク必須です。

https://ja.react.dev/learn/passing-props-to-a-component

投稿2023/09/16 08:40

honey32

総合スコア197

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

echizeyayota

2023/09/19 05:29

honey32 さん。 Reactドキュメントのご提示ありがとうございます。 参考にさせていただきました。
guest

0

ベストアンサー

ModalsetChosenLanguage prop にもechizeyayotaさんの言うところの「useStateフックで管理されている関数」が渡されてきます。

App の中で Modal が使われている部分

jsx

1 {showModal && 2 <Modal 3 setShowModal={setShowModal} 4 chosenLanguage={showModal === "input" ? inputLanguage : outputLanguage} 5 setChosenLanguage={showModal === "input" ? setInputLanguage : setOutputLanguage} 6 />}

を見ると、Modal の prop setChosenLanguage に何を渡しているかというと、

javascript

1showModal === "input" ? setInputLanguage : setOutputLanguage

という式の結果(=式を評価した値)を渡しています。この式の結果は、showModal

  • "input" のときは setInputLanguage
  • "input" ではないときはsetOutputLanguage

になります。setInputLanguagesetOutputLanguage は、App の以下の行

javascript

1 const [inputLanguage, setInputLanguage] = useState("English"); 2 const [outputLanguage, setOutputLanguage] = useState("Japanese");

によって作られており、両方とも useState が返す配列の第2要素として取得される関数ですので、echizeyayotaさんの言うところの「useStateフックで管理されている関数」です。

したがって、ModalsetChosenLanguage propで渡されてくる

javascript

1showModal === "input" ? setInputLanguage : setOutputLanguage

という式(が評価された結果)の値は、showModal"input" に等しいか等しくないかに関わらず、「useStateフックで管理されている関数」であると言えます。

投稿2023/07/17 14:18

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

echizeyayota

2023/07/18 05:49

bataille910 さん いつもコメントありがとうございます Reactを含むJavaScriptの関数というと、"cost hoge = () => console.log()" や "function hoge() => {}"、"const [count, setCount] = useState(0)"などのように定義されているものばかりだと思っていました。 コンポーネントのプロップス名(この場合はsetChosenLanguage)をみて、代入されている値が関数であれば、そのプロップス名は関数として扱えることがわかりました。 今後ともどうぞよろしくお願いします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.44%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問