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

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

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

Next.jsは、Reactを用いたサーバサイドレンダリングなどを行う軽量なフレームワークです。Zeit社が開発しており、nextコマンドでプロジェクトを作成することにより、開発環境整備が整った環境が即時に作成できます。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

React.js

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

解決済

useRefを使おうとするとInvalid hook callが発生するのを解決したい

h_al
h_al

総合スコア2

Next.js

Next.jsは、Reactを用いたサーバサイドレンダリングなどを行う軽量なフレームワークです。Zeit社が開発しており、nextコマンドでプロジェクトを作成することにより、開発環境整備が整った環境が即時に作成できます。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

React.js

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

1回答

0グッド

0クリップ

186閲覧

投稿2022/11/10 07:55

前提

Next.jsでTypescriptを使い、簡単なwebアプリを作成しています。
ボタンを押すと中に書かれている文字が表に入力され、ボタンに何も入力されていない初期状態の場合はボタンを押すとモーダルウィンドウが出てきて、そこでボタンの中身を入力するという仕組みを作ろうとした際に今回のエラーが発生してしまいました。

Typescript, Reactは初学者ですので的はずれなことをしているかもしれませんが、ご容赦くださいませ。

実現したいこと

ここに実現したいことを箇条書きで書いてください。

  • Invalid hook callのエラーを解消する

発生している問題・エラーメッセージ

8 | function Modal ({Label, setLabel}){ > 9 | const LabelRef = useRef(null); | ^ 10 | const handleSubmit = () => { 11 | console.log(Label); 12 | setLabel(LabelRef.current.value);
Unhandled Runtime Error Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons: 1. You might have mismatching versions of React and the renderer (such as React DOM) 2. You might be breaking the Rules of Hooks 3. You might have more than one copy of React in the same app See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.

該当のソースコード

TypeScript

1import React, { useState, useRef } from 'react'; 2 3function Modal ({Label, setLabel}){ 4 const LabelRef = useRef(null); 5 const handleSubmit = () => { 6 console.log(Label); 7 setLabel(LabelRef.current.value); 8 } 9 if (Label1 == "") { 10 return ( 11 <div> 12 <div> 13 商品名を入力してください。 14 <input type = "text" ref={LabelRef} /> 15 <button onClick={handleSubmit} >submit</button> 16 </div> 17 </div> 18 ) 19 } 20 else { 21 return null; 22 } 23} 24 25export default function App() { 26 const Product = "一覧"; 27 const initialState = []; 28 const [namelist, setNamelist] = useState(initialState); 29 const [flag, setFlag] = useState(0); 30 const [Label, setLabel] = useState("") 31 32 const nameClick = () => { 33 Modal(Label,setLabel); 34 setFlag(flag + 1); 35 setNamelist([...namelist, Label]); 36 } 37 38 const delateClick = () => { 39 setFlag(0); 40 setNamelist ([]); 41 alert("delate"); 42 } 43 44 return ( 45 <> 46 <div> 47 <button onClick={nameClick}> 48 {Label} 49 </button> 50 </div> 51 <button onClick={delateClick}> 52 削除 53 </button> 54 <table border={2}> 55 <tr> 56 <th>{Product}</th> 57 </tr> 58 <tr> 59 <td>{flag >= 1 ? namelist[0] : ""}</td> 60 </tr> 61 <tr> 62 <td>{flag >= 2 ? namelist[1] : ""}</td> 63 </tr> 64 <tr> 65 <td>{flag >= 3 ? namelist[2] : ""}</td> 66 </tr> 67 </table> 68 </> 69 70 ); 71} 72

試したこと

こちらのサイトを参考にモーダルウィンドウを表示するコンポーネントを作成しました。
サイトに有るようにjsx内で以下

...略 return ( <> <div> <Modal Label={Label} setLabel={setLabel} /> <button onClick={nameClick_1}> {Label} </button> </div> ...略

のようにpropsを使いデータを渡してしまうと、その時点でモーダルウィンドウが出てしまうため、nameClickの関数内でModalを呼び出し、Labelが初期状態の""である場合だけモーダルウィンドウを出し入力を促せないか試してみたところ今回のエラーが発生しました。

エラーの内容1と3においては確認したところ特に問題がなさそうだったため、2のHooksのルール違反であると予想はしているのですが、トップレベルでの使用であると認識しておりなぜ今回このエラーが発生してるのかがわかりません。

補足情報(FW/ツールのバージョンなど)

yarn 1.21.1
node 16.14.0
next.js 13.0.2
react 18.2.0

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

回答1

0

ベストアンサー

Hooksを使った関数コンポーネントは、Modal()の形で呼び出すことはできません。

<Modal>の形で、JSXに埋め込んで使ってください。

投稿2022/11/10 07:57

maisumakun

総合スコア141322

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

maisumakun

2022/11/10 08:02

> その時点でモーダルウィンドウが出てしまうため JSX内で3項演算子などを使って、必要ないときは描画しないように条件分岐させる、あるいはモーダルの表示非表示もcontrolledなstateとして親で管理する、などの方策を取ってください。
h_al

2022/11/11 10:48

ありがとうございます。 新たにモーダルの表示フラグをstateで管理することで無事動かすことができました。

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

ただいまの回答率
86.12%

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

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

質問する

関連した質問

同じタグがついた質問を見る

Next.js

Next.jsは、Reactを用いたサーバサイドレンダリングなどを行う軽量なフレームワークです。Zeit社が開発しており、nextコマンドでプロジェクトを作成することにより、開発環境整備が整った環境が即時に作成できます。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

React.js

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