前提
React 17.0.2 Material-ui 5.0 を用いてフロントエンド開発を行っています。
テキストフィールド等のUIの情報を2階層のネストしたObjectにまとめて、子コンポーネントにmapでレンダリングさせるプログラムを実装しています。
この際、useRefオブジェクトをObjectに追加しましたが、親コンポ-ネントからRefを参照してフォーカスを合わせることができません。
実現したいこと
親コンポーネントからObjectを渡して、useRefでフォーカスをkey名を指定して移動させたい。
子コンポーネントでonClick等のイベントを実行した際にフォーカスを移動させたいです。
該当のソースコード
React(親コンポーネント)
1import ComponentList from 'components/molecules/ComponentList'; 2import { useState, useEffect, useRef, forwarfRef } from 'react'; 3import Stack from '@mui/material/Stack'; 4import { Typography } from '@material-ui/core'; 5import Snackbar from 'components/atoms/Snackbar'; 6import axios from 'api.js'; 7 8 9const hogeTextFieldRef = useRef(); 10const movehoge=()=>{ 11 componentList1.hogeTextfield2.ref.current.focus() 12} 13const [componentList1, setComponentlist] = useState({ 14 hogeTextfield1: { 15 label: 'hoge', 16 component: 'TextField', 17 value: '', 18 required: true, 19 onClick: movehoge, 20 key: 1, 21 type: 'number', 22 inputProps: { maxLength: 2, pattern: '^[0-9]' } 23 }, 24 hogeTextfield2: { 25 label: 'hoge', 26 component: 'TextField', 27 value: '', 28 required: true, 29 key: 2, 30 type: 'number', 31 ref: hogeTextFieldRef, 32 inputProps: { maxLength: 2, pattern: '^[0-9]' } 33 }, 34 hogeTypography: { 35 label: `hoge見出し`, 36 component: 'Typography', 37 key: 13, 38 xs: 9 39 } 40} 41 return ( 42 <> 43 <Stack spacing={2}> 44 <item> 45 <ComponentList lists={componentList1} setLists={setComponentlist} /> 46 47 </item> 48 </Stack> 49 </> 50 ); 51} 52 53 54
React (子コンポーネント)
1// import Textfield from 'components/atoms/Textfield'; 2import TextField from '@mui/material/TextField'; 3import Button from 'components/atoms/Button'; 4import { MenuItem, Grid, Checkbox, Typography } from '@material-ui/core'; 5import FormControlLabel from '@material-ui/core/FormControlLabel'; 6import * as React from 'react'; 7import Box from '@mui/material/Box'; 8import { useForm, Controller } from 'react-hook-form'; 9import axios from 'api.js'; 10 11const TextfieldList = React.forwardRef(({ lists, setLists }) => ( 12 <Grid container spacing={2} alignItems="center"> 13 {Object.keys(lists).map((key) => { 14 const list = lists[key]; 15 // console.log('list:', list); 16 switch (list.component) { 17 case 'TextField': 18 return ( 19 <Grid item xs={list.xs ? list.xs : 2}> 20 <item> 21 <TextField 22 disabled={list.disabled} 23 fullWidth 24 label={list.label} 25 26 key={list.key} 27 required={list.required} 28 value={list.value} 29 inputRef={list.ref} 30 onChange={(e) => { 31 setLists({ 32 ...lists, 33 [key]: { 34 ...lists[key], 35 value: e.target.value 36 } 37 }); 38 // console.log(list.setValue); 39 // list.setValue(e.target.value); 40 }} 41 42 onKeyPress={(e) => { 43 if (e.key === 'Enter') { 44 list.onClick(lists); 45 } 46 }} 47 variant="outlined" 48 /> 49 </item> 50 </Grid> 51 ); 52 case 'Typography': 53 return ( 54 <Grid item xs={list.xs ? list.xs : 12}> 55 <Typography key={list.key} variant={list.variant}> 56 {list.label} 57 </Typography> 58 </Grid> 59 ); 60 case 'Button': 61 return ( 62 <Grid item xs={list.xs ? list.xs : 10}> 63 <Button key={list.key} label={list.label} variant="contained"> 64 {list.label} 65 </Button> 66 </Grid> 67 ); 68 69 default: 70 return <TextField key={list.key} label={list.label} required={list.required} value="aiu" />; 71 } 72 })} 73 </Grid> 74)); 75 76export default TextfieldList; 77
