実現したいこと
getEquioment()で取得したitemsDataをitemsDataProviderに渡したいです
発生している問題・分からないこと
いろいろなことを試したもののうまくitemsDataを取得する方法がわかりません
エラーメッセージ
error
1Error: async/await is not yet supported in Client Components, only Server Components. This error is often caused by accidentally adding `'use client'` to a module that was originally written for the server.
該当のソースコード
getEquipmentinfo.ts
1'use server'; 2import { JWT } from 'google-auth-library'; // 認証用。 3import { GoogleSpreadsheet } from 'google-spreadsheet'; 4import { itemProps } from 'const/equipmentType'; 5 6// sheetのインスタンスを取得 7const getSheets = () => { 8 // まず認証情報を作る 9 10 // 見られるスコープはどこまでか 11 const scopes = [ 12 'https://www.googleapis.com/auth/spreadsheets', 13 'https://www.googleapis.com/auth/drive.file', 14 ]; 15 // スプシのシートID process.envうんたらは、.env.localに書いてある 16 const sheetId = process.env.SHEET_ID; 17 // サービスアカウントのメアドとパス 18 const clientEmail = 19 process.env.GOOGLE_SERVICE_ACCOUNT_EMAIL; 20 const privateKey = ( 21 process.env.GOOGLE_PRIVATE_KEY as string 22 ).replace(/\\n/g, '\n'); 23 24 // 認証インスタンス作る 25 const jwt = new JWT({ 26 email: clientEmail, 27 key: privateKey, 28 scopes: scopes, 29 }); 30 31 // シートIDと認証情報をセットにして、spreadsheetのインスタンス生成 32 const doc = new GoogleSpreadsheet(sheetId as string, jwt); 33 return doc; 34}; 35 36// itemProps[]型のデータを取得する関数 37export const getEquipmentInfo = async () : Promise<itemProps[]> => { 38 // シートインスタンスつくって 39 const sheet = getSheets(); 40 // GCPからデータ取得 41 await sheet.loadInfo(); 42 // "equipments"というシートを取得 43 const sheetInfo = sheet.sheetsByTitle['equipments']; 44 45 // シートから列データ取得 46 const rows = await sheetInfo.getRows<itemProps>(); 47 console.log(rows); 48 if (rows) { 49 // 辞書の配列の形式にして、各データを返す 50 return rows.map((row) => { 51 return { 52 name: row.get('name'), 53 count: row.get('count'), 54 tag: row.get('tag'), 55 location: row.get('location'), 56 imagePath: row.get('imagePath'), 57 latestUpdate: row.get('latestUpdate'), 58 purchasePlace: row.get('purchasePlace'), 59 threshold: row.get('threshold'), 60 }; 61 }); 62 } else { 63 // ここでエラーを返すようにすることでitemsがundefinedになるのを防ぐ. 64 // 参考: https://zenn.dev/estra/articles/ts-with-promise-type-annotation#promise-%E3%81%AE%E5%9E%8B%E6%B3%A8%E9%87%88 65 return []; 66 } 67}
itemsContext.tsx
1'use client'; 2import { ReactNode, createContext, use, useEffect, useState } from 'react'; 3import { itemProps } from '@/lib/const/equipmentType'; 4import { getEquipmentInfo } from '@/lib/apis/getEquipmentInfo'; 5 6export const ItemsDataContext = createContext({ 7 itemsData: [] as itemProps[], 8}); 9 10export const ItemsDataContextProvider = ({ 11 children, 12}: { 13 children: ReactNode; 14}) => { 15 const [itemsData, setItemsData] = useState<itemProps[]>([]); 16 useEffect(() => { 17 const fetchData = async () => { 18 const data = await getEquipmentInfo(); 19 setItemsData(data); 20 }; 21 fetchData(); 22 }, []); 23 return ( 24 <ItemsDataContext.Provider value={{ itemsData }}> 25 {children} 26 </ItemsDataContext.Provider> 27 ); 28};
試したこと・調べたこと
- teratailやGoogle等で検索した
- ソースコードを自分なりに変更した
- 知人に聞いた
- その他
上記の詳細・結果
- リストPage Routerではなく,App Routerであるため,getStaticPropsなどが使えないこと
- リストServer Actionで行けるかと思い,試したものの,
It is not allowed to define inline "use server" annotated Server Actions in Client Components. To use Server Actions in a Client Component, you can either export them from a separate file with "use server" at the top, or pass them down through props from a Server Component.
と言われてしまう
補足
参考記事
getEquipment内のconsole.logからデータが取得されていることはわかっています
どうぞよろしくお願いいします
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2024/02/20 00:20
2024/02/20 12:56 編集