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

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

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

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

TypeScript

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

React.js

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

Q&A

1回答

141閲覧

【TypeScript + NextJS】ContextProvider子要素のデータ型エラーの解決

REIA

総合スコア26

Next.js

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

TypeScript

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

React.js

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

0グッド

0クリップ

投稿2024/05/05 02:19

実現したいこと

画面状態の遷移をContext + useReducerで外部管理して、
複数のコンポーネントからモードとその更新用関数を参照すること

学習なので本番実装を想定して、React.FC<Props>などは使いたくない

発生している問題・分からないこと

Providerの子要素になっているReactコンポーネントの返り値をすべてReactElementやReactNodeに変えているのにも関わらず なぜかElement[]と判断され、props等が存在しないといわれ怒られている状態なのですが、なぜ、Elementと判断されているのでしょうか?

エラーメッセージ

error

1型 '{ children: Element[]; }' には 型 'ReactElement<any, string | JSXElementConstructor<any>>[]' からの次のプロパティがありません: length, pop, push, concat、29 など。ts(2740)

該当のソースコード

typescript

1export default function MainPage():ReactElement { 2 return ( 3 <DisplayModeProvider> 4 <Header/> 5 <Main/> 6 </DisplayModeProvider> 7 8 ) 9}

TypeScript

1export default function Header():ReactElement{ 2 return ( 3 <div> 4 <img src="/logo.svg" className={styles.logo}/> 5 <Navigation menu_strs = {[ 6 C_MODE_STR.MODE_MUSTLIST_STR, 7 C_MODE_STR.MODE_SETTING_STR, 8 C_MODE_STR.MODE_HOWTONOTICE_STR 9 ]} orders = {C_MENU_ORDERS} 10 ></Navigation> 11 <hr></hr> 12 </div> 13 ); 14}

TypeScript

1export default function Navigation({ 2 menu_strs, 3 orders, 4}:{menu_strs:T_C_MODE_STR[],orders:number[]}):ReactElement{ 5 const {mode,DispatchMode}= useContext(DisplayModeContext); 6 7 8 return ( 9 <div> 10 {/* メニュー一覧 */} 11 <div className={Navigationstyles.menubox}> 12 { 13 orders.map( 14 (order) => { 15 return( 16 <div 17 className={` 18 ${Navigationstyles.menu} 19 ${Navigationstyles.hover_color} 20 ${GetModeStrFromMode(mode) === menu_strs[order] ? 21 Navigationstyles.menu_selected : 22 ""} 23 24 `} 25 onClick={(e) => { 26 DispatchMode( 27 { 28 mode:menu_strs[order] 29 } 30 ) 31 32 } 33 } 34 > 35 <IconLib 36 type = {menu_strs[order]} 37 classname = {Navigationstyles.menu_icon} 38 /> 39 {menu_strs[order]} 40 </div> 41 ) 42 } 43 ) 44 } 45 </div> 46 </div> 47 ) 48}

TypeScript

1import { C_MODE_STR } from "@/resources/Constant"; 2import ListIcon from '@mui/icons-material/List'; 3import SettingsIcon from '@mui/icons-material/Settings'; 4import HelpCenterIcon from '@mui/icons-material/HelpCenter'; 5import { T_C_MODE_STR } from "@/types/types"; 6import { ReactElement } from "react"; 7 8/** 9 * @module IconLib 10 * @description typeに応じて、Iconを返す\ 11 * 新しいアイコンを使用する際はこのモジュールに追加し\ 12 * IconLib経由で使うこと 13 * @param {I_IconlibParam} param : {\ 14 * type : C_MODE_STR内のいずれか\ 15 * classname : 使用したいstylename 必須ではない\ 16 * } 17 */ 18export default function IconLib({type,classname}:{type:T_C_MODE_STR,classname:string}):ReactElement{ 19 // typeの取得 20 let work_classname = ""; 21 if(classname != undefined){ 22 work_classname = classname; 23 } 24 //typeに応じたアイコンの表示 25 switch(type){ 26 case C_MODE_STR.MODE_SETTING_STR: 27 return( 28 <ListIcon className={work_classname}/> 29 ); 30 case C_MODE_STR.MODE_MUSTLIST_STR: 31 return( 32 <SettingsIcon className={work_classname}/> 33 ); 34 case C_MODE_STR.MODE_HOWTONOTICE_STR: 35 return( 36 <HelpCenterIcon className={work_classname}/> 37 ); 38 default: 39 return(<HelpCenterIcon className={work_classname}/>); 40 } 41 42}

TypeScript

1import { useReducer,ReactElement } from "react"; 2import { 3 C_MODE, 4 C_MODE_STR 5} from "../../resources/Constant"; 6import { C_MSG_WARN_TRANSIT 7 } from "@/resources/ErrorWarnString"; 8import { Dispatch,ReducerAction ,useRef} from "react"; 9import type { 10 T_TransitModeAction, 11 T_C_MODE 12} from "@/types/types"; 13import { createContext } from "react"; 14/** 15 * @method TransitModeState 16 * @description 画面状態遷移 17 * @param {T_C_MODE} state 18 * @param {T_TransitModeAction} action {mode: C_MODE_STRに定義されているいずれか} 19 * @returns {T_C_MODE} result_state 遷移判定後の画面状態 20 */ 21export function TransitModeState(state:T_C_MODE,action:T_TransitModeAction):T_C_MODE{ 22 let result_state:T_C_MODE = state; 23 switch(action.mode){ 24 case C_MODE_STR.MODE_MUSTLIST_STR: 25 result_state = C_MODE.MODE_MUSTLIST; 26 case C_MODE_STR.MODE_SETTING_STR: 27 result_state = C_MODE.MODE_SETTING; 28 case C_MODE_STR.MODE_HOWTONOTICE_STR: 29 result_state = C_MODE.MODE_HOWTONOTICE; 30 default: 31 console.warn(C_MSG_WARN_TRANSIT); 32 } 33 34 return result_state; 35} 36 37/** 38 * @method GetModeStrFromMode 39 * @description 現在のMODEをもとにMODE_STRを取得する 40 * @param {number} mode 41 * @return {string} MODE_STR 各モードに紐づけられた、文字列 42 */ 43export function GetModeStrFromMode(mode:number):string{ 44 switch(mode){ 45 case C_MODE.MODE_MUSTLIST: 46 return C_MODE_STR.MODE_MUSTLIST_STR; 47 case C_MODE.MODE_SETTING: 48 return C_MODE_STR.MODE_SETTING_STR; 49 case C_MODE.MODE_HOWTONOTICE: 50 return C_MODE_STR.MODE_HOWTONOTICE_STR; 51 default: 52 return ""; 53 } 54} 55 56 57 58export const DisplayModeContext = createContext( 59 {} as { 60 mode:T_C_MODE, 61 DispatchMode: Dispatch<T_TransitModeAction> 62 } 63); 64 65 66 67 68/** 69 * @module DisplayMode 70 * @method DisplayModeProvider 71 * @description 画面モード遷移用コンテキスト 72 * @param {ReactNode} children contextを使用する際のprovider 73 */ 74 export default function DisplayModeProvider(children:ReactElement[]):ReactElement{ 75 76 77 const [mode, DispatchMode] = useReducer( 78 TransitModeState, 79 C_MODE.MODE_INIT 80 ); 81 82 83 return( 84 <DisplayModeContext.Provider 85 value = { 86 { 87 mode, 88 DispatchMode 89 } 90 } 91 > 92 {children} 93 </DisplayModeContext.Provider> 94 95 ) 96} 97

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

エラー文やProvider 子要素 複数やReactコンポーネントデータ型などで検索
nextjs,react 公式ドキュメント typescriptのページを確認

Providerの子要素すべて(マテリアルUI以外)の戻り値をReactNode,ReactElementに変更
子要素が複数なのが問題なのかとProviderの引数のデータ型をReactNode | ReactNode[] のUnionにしたりReactElementとその配列のユニオンにしたり変更している
ただ、引数のデータ型をユニオンにしてもいかのエラーが出るだけで、進展なし

型 '{ children: Element[]; }' を型 'IntrinsicAttributes & (ReactElement<any, string | JSXElementConstructor<any>> | ReactElement<any, string | JSXElementConstructor<any>>[])' に割り当てることはできません。

補足

特になし

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

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

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

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

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

guest

回答1

0

tsx

1// Before 2 export default function DisplayModeProvider(children:ReactElement[]):ReactElement{ 3 4// After 5 export default function DisplayModeProvider({ children } : { children: ReactElement[] }): ReactElement {

children は、通常の Props と同じで、第一引数として受け取ったオブジェクトのプロパティの一つとして受け取ります。

参照: 公式ドキュメント

https://ja.react.dev/learn/passing-props-to-a-component#passing-jsx-as-children

投稿2024/05/05 07:12

編集2024/05/05 07:12
honey32

総合スコア197

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.44%

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

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

質問する

関連した質問