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

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

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

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

React.js

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

Q&A

1回答

5018閲覧

タブ切り替え時のstate更新

teach

総合スコア1

Next.js

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

React.js

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

0グッド

0クリップ

投稿2020/11/12 02:04

nextjs初心者です。
詰まったところがあるのでご相談させてください。

やろうとしていること・困っている箇所

現在nextjsを使用してAページ、Bページを用意して
共通パーツでタブコンポーネントを用意しています。
Aページのタブを押すとAページが表示され、Bページのタブを押すとBページが表示されるようになっています。

実装自体はできたのですが、lintを走らせた時に以下のエラーが出たので実装方法に不安が出たため相談させて頂きたく思っております。

warning React Hook useEffect has missing dependencies: 'isA', 'isB', and 'props.type'. Either include them or remove the dependency array. You can also do a functional update 'setIsA(i => ...)' if you only need 'isA' in the 'setIsA' call

イメージ説明

コード

pages配下に
Apage、Bpageディレクトリを置いています。

Apage

import React from 'react' import type { NextPage } from 'next' import { ContentPage } from '~/components/pages/ContentPage' type Props = {} const Apage: NextPage<Props> = props => { return ( <> <ContentPage type="A" /> </> ) } export default Apage

Bpage

import React from 'react' import type { NextPage } from 'next' import { ContentPage } from '~/components/pages/ContentPage' type Props = {} const Bpage: NextPage<Props> = props => { return ( <> <ContentPage type="B" /> </> ) } export default Bpage

components/pages配下にContentPageディレクトリを追加しています。

components/pages/ContentPage/index.tsx

import React from 'react' import { Tab } from './tab' type Props = { type?: string } export const ContentPage: React.FC<Props> = props => { return ( <> <Tab currentPage={props.type} /> {props.type == "A" ? ( <p>Aページです。</p> ) : ( <p>Bページです。</p> )} </> ) }

components/pages/ContentPage/tab.tsx

import React from 'react' import React, { useState, useEffect } from 'react' type Props = { type?: string } export const ContentPage: React.FC<Props> = props => { const [isA, setIsA] = useState(false) const [isB, setIsB] = useState(false) useEffect(() => { props.type === 'A' && setIsA(!isA) props.type === 'B' && setIsB(!isB) }, []) return ( <> <div> <p isActived={isA}>Aページ</p> <p isActived={isB}>Bページ</p> </div> </> ) } {* ここにisActived=trueになってる方にborderをつけるcssを記述 *}

このような感じで実装しました。
まとめると
page/配下にApage,Bpageを作成し、
components/pagesの配下にcontentPageを作成
それをpage/配下のApage,Bpageで呼び出す。

contentPage内のindexでは
page/配下のApage,Bpageでそれぞれ渡されるpropsのtypeを判定しテキストを表示。
tabコンポーネントに、渡ってきたprops.typeを渡し
tabコンポーネント内でuseStateでisAとisBのstateを定義。
useEffect内でprops.typeの値を見てstateの値を更新。
stateの値がtrueになってるものにcssでborderをつけるといった感じになっています。

動き自体に問題はないかなと思っているのですが、警告が出ているので
どう書けばいいのか、どう実装するのがいいのかを聞きたいです。

対応したこと

エラー文を翻訳などで確認したところ、
isA,isB,props.typeを依存配列に含めるか、削除してくださいとのことだったので
useEffectの第2引数について調べたところ
第2引数には依存する値を入れるとその値が変わった時にuseEffectが走るとのことなので
今回の場合だとurlが変わったタイミング(Apageか Bpage)だけでしか判断しないので第2引数はから配列にしましたが、それでもうまく動かずどうすればいいのか詰まりました。

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

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

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

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

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

guest

回答1

0

今回の場合だとurlが変わったタイミング(Apageか Bpage)だけでしか判断しないので第2引数はから配列にしましたが

この時点で正しくありません。中でprops.typeが変わったことを検知したいのであれば、それを配列に入れる必要があります(空配列だと、「最初に一度実行した後は、何があっても処理しない」という意味になります)。


現状のコードでは、props.typeABAのように移り変わった場合に、isAはfalseでisBはtrueとなりますが、それは意図した動作でしょうか?

投稿2020/11/12 03:20

maisumakun

総合スコア145184

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

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

teach

2020/11/12 05:55

ご回答頂きありがとうございます。 > この時点で正しくありません。中でprops.typeが変わったことを検知したいのであれば、それを配列に入れる必要があります(空配列だと、「最初に一度実行した後は、何があっても処理しない」という意味になります)。 この部分は配列に[props.type]を入れるべきということでしょうか? > 現状のコードでは、props.typeがA→B→Aのように移り変わった場合に、isAはfalseでisBはtrueとなりますが、それは意図した動作でしょうか? ここはApageとBpageでurl変わるので Apageに初回アクセス時→ isAはtrue, isBはfalse Bpageに初回アクセス時→isAはfalse,isBはtrue になるだけで ApageでBpageへのリンクを押した場合isAもisBもリセットされるものと思っていましたがどうなんでしょうか?
teach

2020/11/12 05:56 編集

手元で動作確認していますが、 何回繰り返しても pageAにいる時にはisAがtrue pageBにいる時にはisBがtrueの状態になっています。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問