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

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

新規登録して質問してみよう
ただいま回答率
85.35%
React Native

React Nativeは、ネイティブモバイルアプリ(iOS/Android)を作成できるJavaScriptフレームワークです。Reactと同じ設計のため、宣言的なコンポーネントでリッチなUIを開発することが可能です。

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

React.js

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

Q&A

解決済

2回答

3572閲覧

TypeError: undefined is not an object (evaluating 'items.rows')

aiai8976

総合スコア112

React Native

React Nativeは、ネイティブモバイルアプリ(iOS/Android)を作成できるJavaScriptフレームワークです。Reactと同じ設計のため、宣言的なコンポーネントでリッチなUIを開発することが可能です。

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

React.js

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

0グッド

0クリップ

投稿2021/08/14 14:58

前提・実現したいこと

react nativeのexpoを利用して家計簿サンプルアプリを作成しながら勉強しています。
その際に以下のようなエラーが出て困っています。
親コンポーネントのuseEffectであらかじめDBから値を取り出してstateに入れているにもかかわらず、
子コンポーネントでundefinedになってしまっています。
useEffectはマウント前に実行してくれるので今回の場合は上手くいくのではないのでしょうか。
この辺りに関してご存知の方がいましたらコメントお願いします。

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

TypeError: undefined is not an object (evaluating 'items.rows')

該当のソースコード

js

1export const CalendarScreen: VFC<Props> = ({ navigation, route }) => { 2 const [items, setItems] = useState<SQLite.SQLResultSet>(); 3 4 useEffect(() => { 5 db.transaction((tx: any) => { 6 tx.executeSql( 7 "select * from costHistoryV3;", 8 [], 9 (_, resultSet: any) => { 10 setItems(resultSet); 11 }, 12 () => { 13 console.log("select fail"); 14 return false; 15 } 16 ) 17 }) 18 }, []); 19 20 return ( 21 <View style={styles.container}> 22 <CustomCalendar items={items} /> 23 <View> 24 {monthlyCostHistory.map((value, index) => { 25 return ( 26 <CostHistory 27 key={index} 28 cost={value.cost} 29 type={value.type} 30 onPress={() => onPress(value.cost)} 31 /> 32 ); 33 })} 34 </View> 35 </View> 36 ); 37};
export const CustomCalendar: VFC<Props> = ({ items }) => { return ( <Calendar theme={{ "stylesheet.calendar.header": { dayTextAtIndex0: { color: "red", }, dayTextAtIndex6: { color: "blue", }, }, }} dayComponent={({ date }) => { // dateが一致するitemを取り出して足し合わせる let plusSum = 0; let minusSum = 0; for (let i = 0; i < items.rows.length; i++){ if (items.rows.item(i).date == date) { if (items.rows.item(i).type == 0) { minusSum += items.rows.item(i).cost; } else { plusSum += items.rows.item(i).cost; } } } return ( <View style={styles.customDayComponent}> <Text style={styles.customDayText}>{date.day}</Text> <Text style={styles.dayPlusCost}>{plusSum}</Text> <Text style={styles.dayMinusCost}>{minusSum}</Text> </View> ); }} /> ); };

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

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

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

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

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

guest

回答2

0

ベストアンサー

useEffectはレンダリングの結果を画面に反映させた後で実行されます。

https://reactjs.org/docs/hooks-reference.html#useeffect

The function passed to useEffect will run after the render is committed to the screen.

なのでuseStateに初期値を渡すか、itemsを参照している箇所でundefinedのチェックが必要になります。

投稿2021/08/14 16:02

nabenabe11234

総合スコア126

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

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

0

useEffectの引数に渡されているhookの処理は、位置づけ的にはマウント後に呼ばれるものです。

Reactのドキュメント/副作用フックの利用法のヒントetcを参照ください

useStateで引数を与えないのであれば初期状態はundefinedになるため、必然的にundefinedが存在するタイミングを前提とした実装をする必要があります。

投稿2021/08/14 15:59

attakei

総合スコア2740

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問