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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Material-UI

Material-UIは、Material Designを利用可能なオープンソースのReact向けUIコンポーネントキットです。

React.js

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

Q&A

解決済

1回答

1593閲覧

親コンポ―ネントで宣言したuseStateを子コンポーネントで更新する方法を知りたい

yuki_20211108

総合スコア14

Material-UI

Material-UIは、Material Designを利用可能なオープンソースのReact向けUIコンポーネントキットです。

React.js

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

0グッド

0クリップ

投稿2022/07/23 07:48

前提

Reactを使ってフォーム機能を作ろうとしています。その中で、プルダウン機能の実装で苦戦中。

実現したいこと

親コンポーネントで宣言したuseStateの変数にプルダウンで選択した項目値を代入したい。
ただし、プルダウン機能は子コンポーネントで実装しています。

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

親コンポーネントで宣言したuseStateを子コンポーネントにProp経由で渡しています。
抱えている問題としては、子コンポーネントで親コンポーネントから受け取ったuseStateの更新がうまくいかないことです。

該当のソースコード

JavaScript(親コンポーネント)

1import React, { useState } from 'react' 2import FormControl from '@mui/material/FormControl'; 3import PullDown from './common/PullDown' 4 5const Form = () => { 6 const [category, setCategory] = useState("") 7 8 return ( 9 <FormControl> 10 <PullDown value={category} pulldown={setCategory}/> 11 </FormControl> 12 ); 13} 14 15export default Form

JavaScript(子コンポーネント,Pulldown.jsx)

1import React from 'react'; 2import { useTheme } from '@mui/material/styles'; 3import OutlinedInput from '@mui/material/OutlinedInput'; 4import InputLabel from '@mui/material/InputLabel'; 5import MenuItem from '@mui/material/MenuItem'; 6import FormControl from '@mui/material/FormControl'; 7import Select from '@mui/material/Select'; 8 9const ITEM_HEIGHT = 48; 10const ITEM_PADDING_TOP = 8; 11const MenuProps = { 12 PaperProps: { 13 style: { 14 maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP, 15 width: 250, 16 }, 17 }, 18}; 19 20const names = [ 21 'アクション', 22 'ミステリー', 23 'スポーツ', 24 'ファンタジー', 25 'ドラマ' 26]; 27 28function getStyles(name, personName, theme) { 29 return { 30 fontWeight: 31 personName.indexOf(name) === -1 32 ? theme.typography.fontWeightRegular 33 : theme.typography.fontWeightMedium, 34 }; 35} 36 37export default function MultipleSelect(prop) { 38 const theme = useTheme(); 39 const [personName, setPersonName] = React.useState([]); 40 41 const handleChange = (event) => { 42 const { 43 target: { value }, 44 } = event; 45 console.log('setPersonName_before_value:',value) 46 setPersonName( 47 typeof value === 'string' ? value.split(',') : value, 48 ); 49 console.log('value:',value) 50 console.log('prop.pulldown_before:',prop.value) 51 prop.pulldown(event) 52 console.log('prop.pulldown_after:',prop.value) 53 }; 54 55 return ( 56 <div> 57 <FormControl sx={{ m: 1, width: 300 }}> 58 <InputLabel id="demo-multiple-name-label">カテゴリ</InputLabel> 59 <Select 60 labelId="demo-multiple-name-label" 61 id="demo-multiple-name" 62 multiple 63 value={personName} 64 onChange={handleChange} 65 input={<OutlinedInput label="カテゴリ" />} 66 MenuProps={MenuProps} 67 > 68 {names.map((name) => ( 69 <MenuItem 70 key={name} 71 value={name} 72 style={getStyles(name, personName, theme)} 73 > 74 {name} 75 </MenuItem> 76 ))} 77 </Select> 78 </FormControl> 79 </div> 80 ); 81}

試したこと

親コンポーネントから受け取ったuseStateの関数(pulldown)前後でログ出力を仕込んだ状態でブラウザからプルダウン項目の選択を実施。
コンソールを確認してみましたが、両方とも空文字のままであることは確認しています。
イメージ説明

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

React 18.1.0
@mui/material 5.8.2

子コンポーネントの実装はMaterial-UI公式ドキュメントに載っているSelectコンポーネントを流用しています。

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

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

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

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

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

guest

回答1

0

ベストアンサー

ぱっと見、MultipleSelect のstate personName が不要なのではと思えました。

以下のように修正でどうでしょう?

common/PullDown.jsx

jsx

1import React from 'react'; 2import { useTheme } from '@mui/material/styles'; 3import OutlinedInput from '@mui/material/OutlinedInput'; 4import InputLabel from '@mui/material/InputLabel'; 5import MenuItem from '@mui/material/MenuItem'; 6import FormControl from '@mui/material/FormControl'; 7import Select from '@mui/material/Select'; 8 9const ITEM_HEIGHT = 48; 10const ITEM_PADDING_TOP = 8; 11const MenuProps = { 12 PaperProps: { 13 style: { 14 maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP, 15 width: 250, 16 }, 17 }, 18}; 19 20const names = [ 21 'アクション', 22 'ミステリー', 23 'スポーツ', 24 'ファンタジー', 25 'ドラマ' 26]; 27 28function getStyles(name, personName, theme) { 29 return { 30 fontWeight: 31 personName.indexOf(name) === -1 32 ? theme.typography.fontWeightRegular 33 : theme.typography.fontWeightMedium, 34 }; 35} 36 37export default function MultipleSelect({ value, onSelect }) { 38 const theme = useTheme(); 39 40 const handleChange = ({ target }) => { 41 onSelect(target.value) 42 }; 43 44 return ( 45 <div> 46 <FormControl sx={{ m: 1, width: 300 }}> 47 <InputLabel id="demo-multiple-name-label">カテゴリ</InputLabel> 48 <Select 49 labelId="demo-multiple-name-label" 50 id="demo-multiple-name" 51 multiple 52 value={value} 53 onChange={handleChange} 54 input={<OutlinedInput label="カテゴリ" />} 55 MenuProps={MenuProps} 56 > 57 {names.map((name) => ( 58 <MenuItem 59 key={name} 60 value={name} 61 style={getStyles(name, value, theme)} 62 > 63 {name} 64 </MenuItem> 65 ))} 66 </Select> 67 </FormControl> 68 </div> 69 ); 70} 71

Form.jsx

jsx

1import React, { useState } from 'react' 2import FormControl from '@mui/material/FormControl'; 3import PullDown from './common/PullDown' 4 5const Form = () => { 6 const [categories, setCategories] = useState([]) 7 8 console.log(categories) 9 10 return ( 11 <FormControl> 12 <PullDown value={categories} onSelect={setCategories}/> 13 </FormControl> 14 ); 15} 16 17export default Form 18

うまくいくと、Form に追加したログ console.log(categories) で、プルダウンの各項目を選択、あるいは非選択にするたびに、選択されている項目の配列が表示されます。

投稿2022/07/23 09:00

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

yuki_20211108

2022/07/24 02:05

こんにちは。 コメントありがとうございます! 修正してくださったコードで動作を確認してみたところ、コメント通りの挙動になっていました。 こちらの希望としていた挙動になっているので、これで学習を進められますm(_ _)m 改めて、ご回答してくださりありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問