You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
7.5 KiB
7.5 KiB
01-APP React Native 项目结构初始化
目标
使用 React Native CLI 创建项目,配置基础依赖和目录结构。
前置要求
- React Native 环境已搭建
- Node.js 18+ 已安装
- Android Studio / Xcode 已配置
实施步骤
步骤 1:创建 React Native 项目
cd I:\apps\demo\healthApps
# 创建项目
npx react-native init app --template react-native-template-typescript
cd app
步骤 2:安装核心依赖
# 导航
npm install @react-navigation/native @react-navigation/native-stack @react-navigation/bottom-tabs
npm install react-native-screens react-native-safe-area-context
# 状态管理
npm install zustand
# 网络请求
npm install axios
# 图表(体质雷达图)
npm install react-native-svg
npm install react-native-gifted-charts
# 存储
npm install @react-native-async-storage/async-storage
# 表单
npm install react-hook-form
# UI 组件
npm install react-native-paper react-native-vector-icons
npm install @types/react-native-vector-icons -D
# 工具
npm install dayjs
步骤 3:配置 iOS 依赖(macOS)
cd ios
pod install
cd ..
步骤 4:创建目录结构
mkdir -p src/api
mkdir -p src/components/common
mkdir -p src/components/survey
mkdir -p src/components/constitution
mkdir -p src/components/chat
mkdir -p src/screens/auth
mkdir -p src/screens/survey
mkdir -p src/screens/constitution
mkdir -p src/screens/chat
mkdir -p src/screens/profile
mkdir -p src/navigation
mkdir -p src/stores
mkdir -p src/hooks
mkdir -p src/utils
mkdir -p src/types
mkdir -p src/assets
步骤 5:创建类型定义
创建 src/types/index.ts:
export interface User {
id: number
phone: string
email: string
nickname: string
avatar: string
survey_completed: boolean
}
export interface HealthProfile {
id: number
name: string
birth_date: string
gender: string
height: number
weight: number
bmi: number
blood_type: string
}
export interface Question {
id: number
constitution_type: string
question_text: string
options: string[]
order_num: number
}
export interface ConstitutionScore {
type: string
name: string
score: number
description: string
}
export interface ConstitutionResult {
primary_constitution: ConstitutionScore
secondary_constitutions: ConstitutionScore[]
all_scores: ConstitutionScore[]
recommendations: Record<string, Record<string, string>>
assessed_at: string
}
export interface Conversation {
id: number
title: string
created_at: string
updated_at: string
}
export interface Message {
id: number
role: 'user' | 'assistant' | 'system'
content: string
created_at: string
}
export interface ApiResponse<T = any> {
code: number
message: string
data: T
}
步骤 6:创建 API 请求基础配置
创建 src/api/request.ts:
import axios from 'axios'
import AsyncStorage from '@react-native-async-storage/async-storage'
import { Alert } from 'react-native'
import type { ApiResponse } from '../types'
const API_BASE_URL = __DEV__
? 'http://10.0.2.2:8080/api' // Android 模拟器
: 'https://your-production-url.com/api'
const request = axios.create({
baseURL: API_BASE_URL,
timeout: 30000,
})
// 请求拦截器
request.interceptors.request.use(
async (config) => {
const token = await AsyncStorage.getItem('token')
if (token) {
config.headers.Authorization = `Bearer ${token}`
}
return config
},
(error) => Promise.reject(error)
)
// 响应拦截器
request.interceptors.response.use(
(response) => {
const res = response.data as ApiResponse
if (res.code !== 0) {
Alert.alert('提示', res.message || '请求失败')
return Promise.reject(new Error(res.message))
}
return res.data
},
(error) => {
if (error.response?.status === 401) {
AsyncStorage.removeItem('token')
// 这里需要导航到登录页,后续在导航配置中处理
}
Alert.alert('错误', error.message || '网络错误')
return Promise.reject(error)
}
)
export default request
步骤 7:创建用户 Store
创建 src/stores/userStore.ts:
import { create } from 'zustand'
import AsyncStorage from '@react-native-async-storage/async-storage'
import type { User } from '../types'
interface UserState {
token: string
user: User | null
isLoggedIn: boolean
surveyCompleted: boolean
setToken: (token: string) => void
setUser: (user: User) => void
logout: () => void
loadToken: () => Promise<void>
}
export const useUserStore = create<UserState>((set, get) => ({
token: '',
user: null,
isLoggedIn: false,
surveyCompleted: false,
setToken: async (token: string) => {
await AsyncStorage.setItem('token', token)
set({ token, isLoggedIn: !!token })
},
setUser: (user: User) => {
set({ user, surveyCompleted: user.survey_completed })
},
logout: async () => {
await AsyncStorage.removeItem('token')
set({ token: '', user: null, isLoggedIn: false, surveyCompleted: false })
},
loadToken: async () => {
const token = await AsyncStorage.getItem('token')
if (token) {
set({ token, isLoggedIn: true })
}
},
}))
步骤 8:更新 App.tsx
更新 App.tsx:
import React, { useEffect, useState } from 'react'
import { StatusBar } from 'react-native'
import { NavigationContainer } from '@react-navigation/native'
import { Provider as PaperProvider } from 'react-native-paper'
import { SafeAreaProvider } from 'react-native-safe-area-context'
import { useUserStore } from './src/stores/userStore'
import RootNavigator from './src/navigation/RootNavigator'
const App = () => {
const [isReady, setIsReady] = useState(false)
const loadToken = useUserStore((state) => state.loadToken)
useEffect(() => {
const init = async () => {
await loadToken()
setIsReady(true)
}
init()
}, [])
if (!isReady) {
return null // 或者显示 Splash Screen
}
return (
<SafeAreaProvider>
<PaperProvider>
<NavigationContainer>
<StatusBar barStyle="dark-content" />
<RootNavigator />
</NavigationContainer>
</PaperProvider>
</SafeAreaProvider>
)
}
export default App
步骤 9:验证项目
# Android
npm run android
# iOS (macOS)
npm run ios
需要创建的文件清单
| 文件路径 | 说明 |
|---|---|
src/types/index.ts |
类型定义 |
src/api/request.ts |
请求封装 |
src/stores/userStore.ts |
用户状态管理 |
App.tsx |
应用入口(更新) |
最终目录结构
app/
├── src/
│ ├── api/
│ │ └── request.ts
│ ├── components/
│ │ ├── common/
│ │ ├── survey/
│ │ ├── constitution/
│ │ └── chat/
│ ├── screens/
│ │ ├── auth/
│ │ ├── survey/
│ │ ├── constitution/
│ │ ├── chat/
│ │ └── profile/
│ ├── navigation/
│ ├── stores/
│ │ └── userStore.ts
│ ├── hooks/
│ ├── utils/
│ ├── types/
│ │ └── index.ts
│ └── assets/
├── App.tsx
├── package.json
├── android/
└── ios/
验收标准
- 项目创建成功
- 依赖安装完成
- 目录结构创建完整
- 模拟器启动正常
- 无报错
预计耗时
20-30 分钟
下一步
完成后进入 04-APP开发/02-导航和布局设计.md