実現したいこと
以下を解決したいです。
axiosを使ったほかの表描画コンポーネントでは遭遇したことのない状況で、申し訳ありませんがご存じでしたらご教示いただけますと幸いです。
- ビルド後に1度だけsetStateが正常に動作する ←ここが特によくわからないです。
- コンポーネント(JSX.Element)のrender();部分を削除してビルド→エラー→再度render();追加してビルド成功した後にのみ上記stateをデータとして使った表のレンダリングが1度だけ動作する
前提
- React(18.2.0)+TypeScriptでWebAPIからaxiosで取得したJSONデータをstateに保持し表データとしてレンダリングしたいと考えています。
- 表の描画には、react-spreadsheet-grid(2.3.1)を使用します。
上記実現のため、ここでは一つのコンポーネントで以下を実装します。
- useEffectによりコンポーネントの初期化時にaxiosでJSONデータを取得
- 上記で取得したJSONデータからカラム情報を取得+setStateしてstateをreact-spreadsheet-gridの<DataSheetGrid/>propsに渡し表をレンダリング
発生している問題・エラーメッセージ
以下2つの問題に直面しています。
(1)ビルド後にのみsetStateが動作する
ビルド後1度目のレンダリング時のみsetStateが正常に動作します。
以降、リロードやルーティング、ブラウザを落とすなどコンポーネントをアンマウントして、再度レンダリング(マウント)してもsetStateが更新されなくなる。
(2)ソースファイル(.tsx)のコンポーネントのrender();部分をクリップボードコピー後削除して一度保存→ホットリロードでビルド→ブラウザエラーが出る→削除したrender();部分を同じ箇所にペースト追加して再度保存→ホットリロードでビルド→最初の一度目のマウント時のみsetStateの内容がレンダリングされる
→二度目以降の再レンダリング(再マウント)時は(1)と同じ
該当のソースコード
TypeScript
1import { useEffect, useState } from 'react' 2import axios, { AxiosResponse } from 'axios' 3import { 4 DataSheetGrid, 5 keyColumn, 6 textColumn, 7 } from 'react-datasheet-grid' 8 import 'react-datasheet-grid/dist/style.css' 9 10 export const MySpreadGridTest=()=> { 11 const [data,setData] = useState([]) 12 const [columns,setColumns] = useState<any[]>([]) 13 const [ loading, setLoading ] = useState(true); 14 const column:any[] = []; 15 let ignore = false; 16 17 useEffect(() => { 18 fetchData(); 19 }, []); 20 21 useEffect(() => { 22 if (!loading) { 23 return; 24 } 25 const newColumns = columns.slice(0, columns.length); 26 setColumns((prev)=>[...newColumns]); 27 setLoading(false); 28 }, [columns]); 29 30 const fetchData = async () => { 31 try { 32 const response = await axios.get('http://endopoint:5000'); 33 if(!ignore){ 34 setData(response.data); 35 if (response.data.length > 0) { 36 Object.keys(response.data[0]).map((key,index)=>{ 37 column.push({ 38 ...keyColumn(key, textColumn), 39 title: key 40 }) 41 }) 42 43 const newColumns = column.slice(0, column.length); 44 setColumns((prev)=>[prev,...newColumns]); 45 46 } 47 } 48 } catch (error) { 49 console.error('Error fetching data: ', error); 50 } 51 ignore = true; 52 }; 53 54 // ↓ここを削除してビルド→エラー→再度追加してビルド→レンダリングが上手くいく 55 return ( 56 <DataSheetGrid 57 value={data} 58 onChange={setData} 59 columns={columns} 60 /> 61 ) 62 }
試したこと
・<React.StrictMode>をコメントアウト
・2回setStateするよう工夫↓
TypeScript
1 useEffect(() => { 2 if (!loading) { 3 return; 4 } 5 const newColumns = columns.slice(0, columns.length); 6 setColumns((prev)=>[...newColumns]); 7 setLoading(false); 8 }, [columns]);
補足情報(FW/ツールのバージョンなど)
・ブラウザはchrome, EDGEで試しました。
各種バージョンは以下です。
・typescript: "^4.9.5"
・axios: "^1.6.2",
・react: "^18.2.0",
・Windows
・VSCode使用
回答1件
あなたの回答
tips
プレビュー