react(+ typecript)组件在更新上下文时不重新启动

发布于 2025-01-23 20:08:25 字数 2688 浏览 0 评论 0原文

我有一个lainingitem组件,该组件使用react.Context获取并将信息设置为/从本地存储中设置。

我要实现的目标是,当组件更新上下文(和本地存储)时,我希望它使用新信息来启动,以便它更新本地按钮的状态。

问题是,尽管上下文似乎已更新以及本地存储的内容,但该项目没有启用。 (但是,当我刷新页面时,我可以看到按钮已更改状态,但是,它表明它可以从上下文中得出这些信息

。 ,我非常感谢您的帮助:)

上下文提供商设置

type FavoritesContextType = {
  favorites: Favorites;
  updateFavorites: (category: StorageCategory, item: string) => void;
};

export const FavoritesContext = createContext<FavoritesContextType>(
  {} as FavoritesContextType
);

const FavoritesProvider: FC = ({ children }) => {
  const [favorites, setFavorites] = useState<Favorites>(
    getFromLocalStorage(SOME_CONSTANT)
  );

  const updateFavorites = (category: StorageCategory, item: string) => {
    updateLocalStorage(category, item);
    setFavorites(favorites);
  };

  return (
    <FavoritesContext.Provider value={{ favorites, updateFavorites }}>
      {children}
    </FavoritesContext.Provider>
  );
};

export const useFavoritesContext = () => useContext(FavoritesContext);

app.tsx

export const App = () => {
  return (
    <FavoritesProvider>
      {/* Some routing wrapper and a few routes each rendering a component */}
      <Route path="/launches" element={<Launches />} />
    </FavoritesProvider>
  )

启动.tsx fairs

export const LaunchItem = ({ launch }: LaunchItemProps) => {
  const { favorites, updateFavorites } = useFavoritesContext();
  const [isFavorite, setIsFavorite] = useState(false);

  useEffect(() => {
    if (favorites) {
      setIsFavorite(
        favorites.launches.includes(launch.flight_number.toString())
      );
    }
  }, [favorites]);

  return (
    {/* The rest of the component, irrelevant */}
    <FavoriteButton
      isFavorite={isFavorite}
      updateFavorites={() => {
        updateFavorites(
          StorageCategory.Launches,
          launch.flight_number.toString()
          );
       }}
   />
  )

faivybutton.tsx

export const FavoriteButton = ({
  isFavorite,
  updateFavorites,
}: FavoriteButtonProps) => {
  const handleClick = (e: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => {
    e.preventDefault();
    updateFavorites();
  };

  return (
    // Using Link vs a Button to be able to preventDefault of parent Link
    <Link
      onClick={handleClick}
    >
    {/* The rest of the component, irrelevant */}

I have a LaunchItem component which uses React.Context to get and set information to/from the local storage.

What I am trying to achieve is that, when the component updates the Context (and local storage), I want it to rerender with the new information, so that it then updates the state of a local button.

The problem is, although the Context seems to be updated as well as the contents of the local storage, the item is not rerendered. (when I refresh the page I can see the button has changed state, however, signifying that it is able to derive that information from the Context just fine.

I will now share some code and hopefully someone is able to understand what I might be missing, I thoroughly appreciate your help :)

Context provider setup

type FavoritesContextType = {
  favorites: Favorites;
  updateFavorites: (category: StorageCategory, item: string) => void;
};

export const FavoritesContext = createContext<FavoritesContextType>(
  {} as FavoritesContextType
);

const FavoritesProvider: FC = ({ children }) => {
  const [favorites, setFavorites] = useState<Favorites>(
    getFromLocalStorage(SOME_CONSTANT)
  );

  const updateFavorites = (category: StorageCategory, item: string) => {
    updateLocalStorage(category, item);
    setFavorites(favorites);
  };

  return (
    <FavoritesContext.Provider value={{ favorites, updateFavorites }}>
      {children}
    </FavoritesContext.Provider>
  );
};

export const useFavoritesContext = () => useContext(FavoritesContext);

App.tsx

export const App = () => {
  return (
    <FavoritesProvider>
      {/* Some routing wrapper and a few routes each rendering a component */}
      <Route path="/launches" element={<Launches />} />
    </FavoritesProvider>
  )

Launches.tsx

export const LaunchItem = ({ launch }: LaunchItemProps) => {
  const { favorites, updateFavorites } = useFavoritesContext();
  const [isFavorite, setIsFavorite] = useState(false);

  useEffect(() => {
    if (favorites) {
      setIsFavorite(
        favorites.launches.includes(launch.flight_number.toString())
      );
    }
  }, [favorites]);

  return (
    {/* The rest of the component, irrelevant */}
    <FavoriteButton
      isFavorite={isFavorite}
      updateFavorites={() => {
        updateFavorites(
          StorageCategory.Launches,
          launch.flight_number.toString()
          );
       }}
   />
  )

FavoriteButton.tsx

export const FavoriteButton = ({
  isFavorite,
  updateFavorites,
}: FavoriteButtonProps) => {
  const handleClick = (e: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => {
    e.preventDefault();
    updateFavorites();
  };

  return (
    // Using Link vs a Button to be able to preventDefault of parent Link
    <Link
      onClick={handleClick}
    >
    {/* The rest of the component, irrelevant */}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

桜花祭 2025-01-30 20:08:25

似乎在您的updateFavorites函数中,您正在调用setFavorites,并传递在现有fairting> fairite值中。尝试将您的updateFavorites函数编写为:

  const updateFavorites = (category: StorageCategory, item: string) => {
    updateLocalStorage(category, item);
    setFavorites(getFromLocalStorage(SOME_CONSTANT));
  };

您可以通过其他方法确定将哪种值传递给setFavorites,但是我将您的getfromlocalstorage函数重复使用。不确定您如何确定该状态价值。

通过这样做,您将确保您要在setFavorites中设置的值与现有fairter值并不相同,因此您将触发RE -使成为。

It seems as though in your updateFavorites function you're calling setFavorites and passing in the existing favorites value. Try instead writing your updateFavorites function as:

  const updateFavorites = (category: StorageCategory, item: string) => {
    updateLocalStorage(category, item);
    setFavorites(getFromLocalStorage(SOME_CONSTANT));
  };

There are other ways you could determine what value to pass to setFavorites but I reused your getFromLocalStorage function as I'm not sure how you're determining that state value.

By doing it this way you'll ensure that the value you're setting in setFavorites isn't the same as the existing favorites value and thus you'll trigger a re-render.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文