feat: 增强FeedListFeature和MeFeature的首次加载逻辑

- 在FeedListFeature和MeFeature中新增isFirstLoad状态,确保仅在首次加载时请求数据。
- 更新MainView以简化视图切换逻辑,使用isHidden修饰符控制视图显示。
- 新增View+isHidden扩展,提供视图隐藏功能,提升代码可读性和复用性。
This commit is contained in:
edwinQQQ
2025-07-24 10:20:12 +08:00
parent 3a74547684
commit 25fec8a2e6
5 changed files with 32 additions and 31 deletions

View File

@@ -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:
// //

View File

@@ -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()
} }
} }

View File

@@ -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

View 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
}
}
}

View File

@@ -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)
// //