首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >不使用状态的按钮单击新值的Rerender映射

不使用状态的按钮单击新值的Rerender映射
EN

Stack Overflow用户
提问于 2022-11-11 06:15:41
回答 2查看 42关注 0票数 0

所以,当我点击"Mark“按钮时,我一直在试图找出如何用新的项目重新绘制项目地图。我尝试将这些项放在一个useState中,并按一下按钮更新状态,但问题是当我设置状态时,它总是一个呈现,因为set状态是异步的。我将如何实现这一目标?

代码语言:javascript
复制
const Main: React.FC<MainProps> = (props) => {
  // Get All Feeds
  const feeds = trpc.feed.getAllFeeds.useQuery();

  // Get Items
  let unsorteditems;
  if (props.FeedType == "one") {
    unsorteditems = trpc.feed.getItemsFromFeed.useQuery({
      feedId: props.feedId,
    });
  } else if (props.FeedType == "readalready") {
    unsorteditems = trpc.feed.getReadItems.useQuery();
  } else {
    unsorteditems = trpc.feed.getFeedItemsFromAllFeeds.useQuery();
  }

  // Sort Items than add title, logo, and markedAsRead
  const sorteditems = unsorteditems.data?.sort(
    (objA, objB) => Number(objB.createdAt) - Number(objA.createdAt)
    // Replace in other order to sort in reverse
  );
  let items = sorteditems?.map((item) => {
    const feed = feeds.data?.find((feed) => feed.id == item.feedId);
    return {
      ...item,
      feedTitle: feed?.title,
      feedLogoUrl: feed?.LogoUrl,
      markedAsRead: false,
    };
  });

  const feedName = items?.[0]?.feedTitle;

  // Mark Read function
  const markreadmutation = trpc.feed.markReadUsingUpsert.useMutation();
  const onClickMarkRead = async (itemId: string) => {
    markreadmutation.mutate({ itemId: itemId });
  };

  // I tried this but it didn't work, and I can't use state because its async and dosent update in time
  function updateItems(index: number) {
    const newItems = items?.map((item, i) => {
      if (i == index) {
        return {
          ...item,
          markedAsRead: true,
        };
      } else {
        return item;
      }
    });
    items = newItems;
  }

  return (
    <>
      {/* I removed alot of code here to make it easier to understand so css may look weird */}
      {/* <!-- Main --> */}
      <div className="basis-5/12 border-l border-slate-300/40">
        <h1 className="sticky top-0 z-50 border-b border-slate-300/40 bg-opacity-60 bg-clip-padding py-2 pl-2 text-xl font-bold backdrop-blur-xl backdrop-filter">
          {props.FeedType == "one"
            ? feedName
            : props.FeedType == "all"
            ? "All Feeds"
            : props.FeedType == "readalready"
            ? "Recently Read"
            : "Woops"}
        </h1>
        <div>
          {items?.length == 0 && <p>No Items</p>}
          {items?.map((item, i) => (
            <div
              className={`border-slate-300/4 relative flex h-28 flex-col border-b ${
                item.markedAsRead ? "bg-gray-200" : "bg-white"
              }`}
              key={item.id}
            >
              {/* ^^^ If item is marked read it will be grayed out ^^^ */}
              <button
                onClick={() => {
                  // THIS BUTTON
                  // When I click this is should rerender the map with the item marked as read
                  onClickMarkRead(item.id);
                  updateItems(i);
                }}
              >
                [Mark Read]
              </button>
            </div>
          ))}
        </div>
      </div>
    </>
  );
};
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-11-11 06:40:50

你最好用状态。您不能在React组件的第一次呈现时访问异步代码。为了使用项的最新值,应该将项存储在状态中,然后为异步调用和项操作(排序等)创建useCallback函数,最后在useEffect中调用该函数。看起来会是这样的:

代码语言:javascript
复制
const [items, setItems] = useState([]);

const getItems = useCallback( async() => {
  const fetchedItems = await yourFetchFunction();
  setItems(fetchedItems);
}, []);

useEffect(() => {
  getItems();
}, [getItems]);
票数 1
EN

Stack Overflow用户

发布于 2022-11-11 08:02:52

单击该按钮后,只应在等待突变后才调用updateItems。在当前代码中,提供同步调用它。您可以在onClickMarkRead中添加它。在其中传递索引并尝试如下所示(在updateItems设置项更新后处于状态):

代码语言:javascript
复制
const onClickMarkRead = async (itemId: string, index: number) => {
  await markreadmutation.mutate({ itemId: itemId });
  updateItems(index);
};

如果它仍然不能工作,您可以通过jsFiddle、CodePen或GitHub向整个组件提供最新的代码更改,这样我就可以看到并最终使用它。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74398681

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档