Rork は自然言語でアプリを作れる素晴らしいツールですが、生成されたコードをそのまま使うと特定のパターンのエラーが出ることがあります。「なぜかビルドが通らない」「アプリが起動したけれどすぐクラッシュする」「UIはできているのに動かない」――これらの多くは、AI 生成コードに共通するいくつかのパターンに起因しています。
パターン1:TypeScript 型エラー(Type Mismatch)
症状
Type 'string | undefined' is not assignable to type 'string'
Object is possibly 'undefined'
Property 'xxx' does not exist on type 'yyy'
なぜ起きるか
Rork(内部的には React Native / Expo ベース)が生成するコードは、API のレスポンスや props の型を any や広い型で定義することがあります。後から TypeScript の厳格な型チェックが通らなくなります。
即時修正
オプショナルチェイニングと nullish 合体演算子の追加:
// ❌ エラーが出るコード
const userName = user.profile.name;
const price = product.price.toFixed(2);
// ✅ 修正済み
const userName = user?.profile?.name ?? '名前未設定';
const price = (product?.price ?? 0).toFixed(2);型アサーションの活用(暫定対処):
// APIレスポンスが型不明の場合
interface UserResponse {
id: string;
name: string;
email: string;
}
const user = response.data as UserResponse;プロンプトによる予防
Rork へのプロンプトに「TypeScript strict モードに対応した厳密な型定義を使ってください。any 型は避けてください」と明示すると、生成コードの型安全性が向上します。
パターン2:インポートエラー(Module Not Found)
症状
Cannot find module 'expo-camera' or its corresponding type declarations
Unable to resolve module @react-navigation/native
Module '"react-native"' has no exported member 'StatusBar'
なぜ起きるか
Rork が生成するコードが参照しているライブラリが、プロジェクトの package.json に含まれていない場合に発生します。Expo SDK のバージョンによって API が変わり、古いモジュール名を参照してしまうこともあります。
即時修正
不足パッケージのインストール:
Rork の場合、チャット欄で「〇〇 のインポートエラーが出ています。必要なパッケージを追加してください」と依頼するとパッケージの追加も対応してくれます。手動で修正する場合:
# Expoプロジェクトへの追加
npx expo install expo-camera
# React Navigation の場合
npx expo install @react-navigation/native @react-navigation/stack
npx expo install react-native-screens react-native-safe-area-contextモジュール名の更新(Expo SDK v50以降の変更例):
// ❌ 古いインポート
import { StatusBar } from 'react-native';
// ✅ 新しいインポート(Expo SDK 50+)
import { StatusBar } from 'expo-status-bar';プロンプトによる予防
「Expo SDK 52 に対応したコードを生成してください。古いAPIを使わないよう注意してください」と Rork に伝えることで、最新の API を使ったコードが生成されやすくなります。
パターン3:状態管理の競合(State Race Condition)
症状
- UIは正しく表示されているのに、ボタンを押しても反応しないことがある
- データが更新されているはずなのにリストが古い内容を表示し続ける
- 複数回タップすると画面が想定外の状態になる
なぜ起きるか
AI が生成するコードでは、複数の useState が同時に更新される際の順序や、useEffect の依存配列が不完全な場合に、状態の競合(race condition)が起きることがあります。
即時修正
関数型アップデートで最新の状態を保証:
// ❌ 古い状態を参照してしまう可能性がある
const handleAdd = () => {
setItems([...items, newItem]);
setCount(count + 1);
};
// ✅ 関数型アップデートで最新値を使う
const handleAdd = () => {
setItems(prev => [...prev, newItem]);
setCount(prev => prev + 1);
};useEffect の依存配列の修正:
// ❌ 依存配列が不完全
useEffect(() => {
fetchUserData(userId);
}, []); // userId が変わっても再実行されない
// ✅ 正しい依存配列
useEffect(() => {
fetchUserData(userId);
}, [userId]); // userId が変わるたびに再実行非同期処理のクリーンアップ:
useEffect(() => {
let isMounted = true;
const loadData = async () => {
const data = await fetchData();
if (isMounted) {
setData(data); // アンマウント後のセット更新を防ぐ
}
};
loadData();
return () => {
isMounted = false;
};
}, []);プロンプトによる予防
「状態更新は関数型アップデートを使ってください。useEffect の依存配列を正確に設定してください」と Rork に指示すると改善が期待できます。
パターン4:非同期処理のエラーハンドリング漏れ
症状
- API 呼び出し中にアプリがフリーズする
- ネットワークエラーが発生するとアプリがクラッシュする
- 読み込み中の表示がいつまでも消えない
なぜ起きるか
AI が生成するコードは、ハッピーパス(正常系)のコードは書けますが、エラーハンドリング・ローディング状態・タイムアウト処理が省略されることがよくあります。
即時修正
完全な非同期処理パターン:
const [data, setData] = useState<UserData | null>(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const fetchUserData = async (userId: string) => {
setLoading(true);
setError(null);
try {
// タイムアウト付きフェッチ
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 10000); // 10秒
const response = await fetch(`/api/users/${userId}`, {
signal: controller.signal
});
clearTimeout(timeoutId);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const json = await response.json();
setData(json);
} catch (err) {
if (err instanceof Error) {
if (err.name === 'AbortError') {
setError('通信がタイムアウトしました。もう一度お試しください。');
} else {
setError(`エラーが発生しました: ${err.message}`);
}
}
} finally {
setLoading(false); // 必ずローディングを解除
}
};UI での状態表示:
if (loading) return <ActivityIndicator size="large" />;
if (error) return (
<View>
<Text>{error}</Text>
<Button title="再試行" onPress={() => fetchUserData(userId)} />
</View>
);
if (!data) return null;プロンプトによる予防
「API 呼び出しは必ずローディング状態・エラー状態・タイムアウト処理を含めてください」と明示することで、より堅牢なコードが生成されます。
パターン5:ナビゲーションエラー(Navigation Type Errors)
症状
Argument of type '"ProfileScreen"' is not assignable to parameter of type 'never'
The action 'NAVIGATE' with payload was not handled by any navigator
Cannot read property 'navigate' of undefined
なぜ起きるか
React Navigation の型定義が不完全、またはナビゲーターのネスト(Stack の中に Tab など)が正しく設定されていない場合に発生します。Rork が生成するコードでは、ルート名の型定義が省略されることがあります。
即時修正
型安全なナビゲーション定義:
// 型定義ファイル(navigation/types.ts)
export type RootStackParamList = {
Home: undefined;
Profile: { userId: string };
Settings: undefined;
Chat: { chatId: string; userName: string };
};
// useNavigation に型を付ける
import { useNavigation } from '@react-navigation/native';
import { StackNavigationProp } from '@react-navigation/stack';
type NavigationProp = StackNavigationProp<RootStackParamList>;
const MyComponent = () => {
const navigation = useNavigation<NavigationProp>();
const goToProfile = () => {
navigation.navigate('Profile', { userId: '123' });
// ✅ 型チェックが効くので、間違ったパラメータは事前に検出される
};
return <Button title="プロフィールへ" onPress={goToProfile} />;
};ネストされたナビゲーターの型定義:
export type TabParamList = {
HomeTab: undefined;
ProfileTab: undefined;
};
export type RootStackParamList = {
Auth: undefined;
Main: NavigatorScreenParams<TabParamList>;
Modal: { message: string };
};プロンプトによる予防
「React Navigation の型定義(RootStackParamList など)を必ず含めてください。型安全なナビゲーションを実装してください」と Rork に伝えましょう。
Rork でのデバッグを効率化する3つのヒント
1. Expo Go / 開発ビルドのコンソールを活用する
Expo Go を使っている場合は、シェイクジェスチャーで開発メニューを開くか、ターミナルの Metro バンドラーのログでエラーの詳細を確認できます。
2. エラーメッセージをそのまま Rork に貼り付ける
エラーが出たら、エラーメッセージ全文をコピーして Rork のチャットに貼り付けてください。「このエラーを修正してください」と伝えるだけで、多くの場合は適切な修正を提案してくれます。
3. 段階的に機能を追加していく
最初から多機能なアプリを一度に生成しようとすると、複雑なエラーが重なりやすくなります。「まず基本的な一覧表示だけ作る → 動作確認 → 次の機能を追加」という段階的なアプローチが、結果的に早く完成します。
全体を振り返って
Rork の AI 生成コードでよく起きるエラーは、型エラー・インポート不足・状態管理の競合・エラーハンドリング漏れ・ナビゲーション型定義の不備の5パターンに集約されます。プロンプトで事前に対策を伝えることと、エラーが出たらエラーメッセージを Rork に共有することで、多くの問題はスムーズに解決できます。アプリ開発を楽しんでいただける一助になれば幸いです。