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

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

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

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

TypeScript

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

React.js

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

Q&A

解決済

1回答

630閲覧

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

h_al

総合スコア3

Next.js

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

TypeScript

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

React.js

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

0グッド

0クリップ

投稿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

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

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

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

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

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

guest

回答1

0

ベストアンサー

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

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

投稿2022/11/10 07:57

maisumakun

総合スコア145183

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

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

maisumakun

2022/11/10 08:02

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

2022/11/11 10:48

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問