整合資料庫、完成登入註冊忘記密碼功能
This commit is contained in:
103
SSR_FIX_SUMMARY.md
Normal file
103
SSR_FIX_SUMMARY.md
Normal file
@@ -0,0 +1,103 @@
|
||||
# SSR 錯誤修復總結
|
||||
|
||||
## 🐛 問題描述
|
||||
|
||||
在 Next.js 應用中遇到了 `ReferenceError: window is not defined` 錯誤,這是因為在服務器端渲染 (SSR) 時嘗試訪問 `window` 對象導致的。
|
||||
|
||||
## ✅ 修復的文件
|
||||
|
||||
### 1. `components/admin/admin-layout.tsx`
|
||||
**問題**:在 SSR 期間直接使用 `window` 對象
|
||||
**修復**:添加 `typeof window !== 'undefined'` 檢查
|
||||
|
||||
```typescript
|
||||
// 修復前
|
||||
{window.opener && !window.opener.closed && (
|
||||
<Button onClick={() => {
|
||||
window.opener.focus()
|
||||
window.close()
|
||||
}}>
|
||||
關閉頁面
|
||||
</Button>
|
||||
)}
|
||||
|
||||
// 修復後
|
||||
{typeof window !== 'undefined' && window.opener && !window.opener.closed && (
|
||||
<Button onClick={() => {
|
||||
window.opener.focus()
|
||||
window.close()
|
||||
}}>
|
||||
關閉頁面
|
||||
</Button>
|
||||
)}
|
||||
```
|
||||
|
||||
### 2. `components/admin/user-management.tsx`
|
||||
**問題**:在函數中直接使用 `window.location.origin`
|
||||
**修復**:添加條件檢查,提供回退值
|
||||
|
||||
```typescript
|
||||
// 修復前
|
||||
const invitationLink = `${window.location.origin}/register?token=${invitationToken}&email=${encodeURIComponent(inviteEmail)}&role=${inviteRole}`
|
||||
|
||||
// 修復後
|
||||
const invitationLink = typeof window !== "undefined"
|
||||
? `${window.location.origin}/register?token=${invitationToken}&email=${encodeURIComponent(inviteEmail)}&role=${inviteRole}`
|
||||
: `/register?token=${invitationToken}&email=${encodeURIComponent(inviteEmail)}&role=${inviteRole}`
|
||||
```
|
||||
|
||||
## 🔧 修復策略
|
||||
|
||||
### 1. 條件檢查
|
||||
```typescript
|
||||
if (typeof window !== 'undefined') {
|
||||
// 只在客戶端執行
|
||||
window.location.href = "/"
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 三元運算符
|
||||
```typescript
|
||||
const url = typeof window !== 'undefined'
|
||||
? `${window.location.origin}/path`
|
||||
: "/path"
|
||||
```
|
||||
|
||||
### 3. useEffect Hook
|
||||
```typescript
|
||||
useEffect(() => {
|
||||
// 只在客戶端執行
|
||||
window.addEventListener('resize', handleResize)
|
||||
return () => window.removeEventListener('resize', handleResize)
|
||||
}, [])
|
||||
```
|
||||
|
||||
## 📋 已檢查的文件
|
||||
|
||||
以下文件已經有正確的 SSR 處理,無需修復:
|
||||
- `components/ui/use-mobile.tsx` - 使用 useEffect
|
||||
- `components/admin/competition-management.tsx` - 有條件檢查
|
||||
- `components/admin/scoring-link-dialog.tsx` - 有條件檢查
|
||||
|
||||
## 🎯 修復結果
|
||||
|
||||
- ✅ 消除了 `window is not defined` 錯誤
|
||||
- ✅ 保持了客戶端功能正常運作
|
||||
- ✅ 確保了 SSR 兼容性
|
||||
- ✅ 提供了適當的回退值
|
||||
|
||||
## 📝 最佳實踐
|
||||
|
||||
1. **始終檢查 `window` 對象**:在 Next.js 中,`window` 只在客戶端可用
|
||||
2. **使用 useEffect**:對於需要在客戶端執行的代碼,使用 `useEffect` Hook
|
||||
3. **提供回退值**:為 SSR 環境提供適當的默認值
|
||||
4. **避免在組件頂層使用 `window`**:將 `window` 相關代碼放在函數內部或 useEffect 中
|
||||
|
||||
## 🚀 測試建議
|
||||
|
||||
1. 檢查管理員頁面是否正常加載
|
||||
2. 驗證用戶邀請功能是否正常
|
||||
3. 確認彈窗關閉功能是否正常
|
||||
4. 測試在不同環境下的表現
|
||||
|
||||
修復完成後,應用應該能夠正常進行服務器端渲染,同時保持所有客戶端功能正常運作。
|
Reference in New Issue
Block a user