feat: 增强FeedListFeature和MeFeature的首次加载逻辑
- 在FeedListFeature和MeFeature中新增isFirstLoad状态,确保仅在首次加载时请求数据。 - 更新MainView以简化视图切换逻辑,使用isHidden修饰符控制视图显示。 - 新增View+isHidden扩展,提供视图隐藏功能,提升代码可读性和复用性。
This commit is contained in:
@@ -5,6 +5,7 @@ import ComposableArchitecture
|
|||||||
struct FeedListFeature {
|
struct FeedListFeature {
|
||||||
@Dependency(\.apiService) var apiService
|
@Dependency(\.apiService) var apiService
|
||||||
struct State: Equatable {
|
struct State: Equatable {
|
||||||
|
var isFirstLoad: Bool = true
|
||||||
var feeds: [Feed] = [] // 预留 feed 内容
|
var feeds: [Feed] = [] // 预留 feed 内容
|
||||||
var isLoading: Bool = false
|
var isLoading: Bool = false
|
||||||
var error: String? = nil
|
var error: String? = nil
|
||||||
@@ -35,9 +36,8 @@ struct FeedListFeature {
|
|||||||
func reduce(into state: inout State, action: Action) -> Effect<Action> {
|
func reduce(into state: inout State, action: Action) -> Effect<Action> {
|
||||||
switch action {
|
switch action {
|
||||||
case .onAppear:
|
case .onAppear:
|
||||||
// 只在首次加载时请求 feed 数据
|
guard state.isFirstLoad else { return .none }
|
||||||
guard !state.isLoaded else { return .none }
|
state.isFirstLoad = false
|
||||||
state.isLoaded = true
|
|
||||||
return .send(.fetchFeeds)
|
return .send(.fetchFeeds)
|
||||||
case .reload:
|
case .reload:
|
||||||
// 下拉刷新,重置状态并请求第一页
|
// 下拉刷新,重置状态并请求第一页
|
||||||
|
@@ -103,10 +103,10 @@ struct MainFeature: Reducer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 设置页作用域
|
// 设置页作用域
|
||||||
.ifLet(\ .settingState, action: /Action.settingAction) {
|
.ifLet(\ .settingState, action: \.settingAction) {
|
||||||
SettingFeature()
|
SettingFeature()
|
||||||
}
|
}
|
||||||
.ifLet(\ .appSettingState, action: /Action.appSettingAction) {
|
.ifLet(\ .appSettingState, action: \.appSettingAction) {
|
||||||
AppSettingFeature()
|
AppSettingFeature()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -5,6 +5,7 @@ import ComposableArchitecture
|
|||||||
struct MeFeature {
|
struct MeFeature {
|
||||||
@Dependency(\.apiService) var apiService
|
@Dependency(\.apiService) var apiService
|
||||||
struct State: Equatable {
|
struct State: Equatable {
|
||||||
|
var isFirstLoad: Bool = true
|
||||||
var userInfo: UserInfo?
|
var userInfo: UserInfo?
|
||||||
var isLoadingUserInfo: Bool = false
|
var isLoadingUserInfo: Bool = false
|
||||||
var userInfoError: String?
|
var userInfoError: String?
|
||||||
@@ -32,17 +33,9 @@ struct MeFeature {
|
|||||||
func reduce(into state: inout State, action: Action) -> Effect<Action> {
|
func reduce(into state: inout State, action: Action) -> Effect<Action> {
|
||||||
switch action {
|
switch action {
|
||||||
case .onAppear:
|
case .onAppear:
|
||||||
guard state.uid > 0 else { return .none }
|
guard state.isFirstLoad else { return .none }
|
||||||
state.isLoadingUserInfo = true
|
state.isFirstLoad = false
|
||||||
state.isLoadingMoments = true
|
return .send(.refresh)
|
||||||
state.userInfoError = nil
|
|
||||||
state.momentsError = nil
|
|
||||||
state.page = 1
|
|
||||||
state.hasMore = true
|
|
||||||
return .merge(
|
|
||||||
fetchUserInfo(uid: state.uid),
|
|
||||||
fetchMoments(uid: state.uid, page: 1, pageSize: state.pageSize)
|
|
||||||
)
|
|
||||||
case .refresh:
|
case .refresh:
|
||||||
guard state.uid > 0 else { return .none }
|
guard state.uid > 0 else { return .none }
|
||||||
state.isRefreshing = true
|
state.isRefreshing = true
|
||||||
|
12
yana/Views/Components/View+isHidden.swift
Normal file
12
yana/Views/Components/View+isHidden.swift
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
extension View {
|
||||||
|
@ViewBuilder
|
||||||
|
func isHidden(_ hidden: Bool) -> some View {
|
||||||
|
if hidden {
|
||||||
|
self.opacity(0).allowsHitTesting(false)
|
||||||
|
} else {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -18,22 +18,18 @@ struct MainView: View {
|
|||||||
.ignoresSafeArea(.all)
|
.ignoresSafeArea(.all)
|
||||||
// 主内容
|
// 主内容
|
||||||
ZStack {
|
ZStack {
|
||||||
switch viewStore.selectedTab {
|
FeedListView(store: store.scope(
|
||||||
case .feed:
|
state: \.feedList,
|
||||||
FeedListView(store: store.scope(
|
action: \.feedList
|
||||||
state: \.feedList,
|
))
|
||||||
action: \.feedList
|
.isHidden(viewStore.selectedTab != .feed)
|
||||||
))
|
MeView(
|
||||||
.transition(.opacity)
|
store: store.scope(
|
||||||
case .other:
|
state: \.me,
|
||||||
MeView(
|
action: \.me
|
||||||
store: store.scope(
|
|
||||||
state: \.me,
|
|
||||||
action: \.me
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
.transition(.opacity)
|
)
|
||||||
}
|
.isHidden(viewStore.selectedTab != .other)
|
||||||
}
|
}
|
||||||
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||||
// 测试按钮
|
// 测试按钮
|
||||||
|
Reference in New Issue
Block a user