React Context子组件循环更新状态失效问题及解决
React Context状态更新问题:forEach调用setter失效,改用findIndex解决
我尝试使用React Context API管理状态,用于渲染无法通过props传递值的徽章。单独调用setUnreadNotif(true/false)时能正常更新布尔值,但在遍历数组的forEach方法中调用该setter时未达预期效果。已确认Provider已正确包裹应用,尝试多种方法无果后,改用findIndex替代forEach解决了问题。
Context代码
import React, { createContext, Dispatch, SetStateAction, useContext, useState, } from 'react'; import { getContentCards } from 'ThisProject/src/utils/braze'; import { ContentCard } from 'react-native-appboy-sdk'; export interface NotificationsContextValue { unreadNotif: boolean; setUnreadNotif: Dispatch<SetStateAction<boolean>>; } export const defaultNotificationsContextValue: NotificationsContextValue = { unreadNotif: false, setUnreadNotif: (prevState: SetStateAction<boolean>) => prevState, }; const NotificationsContext = createContext<NotificationsContextValue>( defaultNotificationsContextValue, ); function NotificationsProvider<T>({ children }: React.PropsWithChildren<T>) { const [unreadNotif, setUnreadNotif] = useState<boolean>(false); return ( <NotificationsContext.Provider value={{ unreadNotif, setUnreadNotif, }}> {children} </NotificationsContext.Provider> ); } function useNotifications(): NotificationsContextValue { const context = useContext(NotificationsContext); if (context === undefined) { throw new Error('useUser must be used within NotificationsContext'); } return context; } export { NotificationsContext, NotificationsProvider, useNotifications };
子组件代码
export default function NotificationsPage({ navigation, }: { navigation: NavigationProp<StackParamList>; }) { const [notificationCards, setNotificationCards] = useState< ExtendedContentCard[] >([]); const user = useUser(); const { setUnreadNotif } = useNotifications(); const getCards = (url: string) => { if (url.includes('thisproject:')) { Linking.openURL(url); } else { navigation.navigate(ScreenIdentifier.NotificationsStack.id, { screen: ScreenIdentifier.NotificationsWebView.id, // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore params: { uri: `${getTrustedWebAppUrl()}${url}`, title: 'Profile', }, }); } getContentCards((response: ContentCard[]) => { response.forEach((card) => { if (card.clicked === false) { setUnreadNotif(true); } }); }); Braze.requestContentCardsRefresh(); }; return ( <ScrollView style={styles.container}> <View style={styles.contentContainer}> {notificationCards?.map((item: ExtendedContentCard) => { return ( <NotificationCard onPress={getCards} key={item.id} id={item.id} title={item.title} description={item.cardDescription} image={item.image} clicked={item.clicked} ctaTitle={item.domain} url={item.url} /> ); })} </View> </ScrollView> ); }
问题解决
我放弃使用forEach,改用findIndex解决了问题,代码如下:
getContentCards((response: ContentCard[]) => { response.findIndex((card) => { if (card.clicked === false) { setUnreadNotif(true); } setUnreadNotif(false); }); });
内容的提问来源于stack exchange,提问作者kinzito17
相关产品推荐
相关产品推荐

