You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 21:01:53