Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Personalized strategy ordering enhancement #1636

Merged
merged 20 commits into from
May 3, 2024

Conversation

otsalex
Copy link
Collaborator

@otsalex otsalex commented Mar 28, 2024

Issue #1627

Description

Added ordering for strategies on vaults page based on 4 priorities:

    • strategies that have similar deposit assets compared to users wallet ( if wallet is connected).
    • strategies that are newer than 4 weeks - also have "new" tag.
    • strategies that have Sommelier rewards.
    • TVL

Changes

  • Added sorting function on strategies data, before data gets injected to table.
  • Solved some Next.js and memory leak errors from console.

Summary by CodeRabbit

  • New Features
    • Enhanced sorting and filtering of strategies on the homepage based on user holdings, new strategies, rewards, and TVL.
    • Added support for additional tokens (WETH, wstETH, rETH) and created mappings for accepted deposit tokens by chain (Ethereum, Arbitrum, Optimism).
  • Bug Fixes
    • Adjusted button functionality in WithdrawButton for improved conditional rendering based on props.
    • Fixed naming conflicts and streamlined state management in components like PortfolioCard and LayoutWithSidebar.
  • Refactor
    • Updated various components (DepositAndWithdrawButton, ApyPerformanceCard, multiple forms) to use the useUserBalance hook for a more accurate retrieval of user balance data.
    • Simplified error handling in data fetching hooks and actions.
  • Documentation
    • Enhanced comments and documentation related to custom reward APY overrides and deposit tokens retrieval.
  • Chores
    • Removed unused imports and simplified assignments in data fetching hooks and actions.

Copy link

vercel bot commented Mar 28, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
sommelier-web ✅ Ready (Inspect) Visit Preview 💬 Add feedback May 3, 2024 7:06am

Copy link

coderabbitai bot commented Mar 28, 2024

Walkthrough

The changes in this update encompass a comprehensive refinement of component functionality, state management, and data handling across various files to elevate user experience and optimize system performance. These updates include adjustments to hook usage, variable naming for clarity, and enhancements in data retrieval mechanisms throughout the codebase.

Changes

File Path Change Summary
.../Nav.tsx, .../LayoutWithSidebar.tsx Updated state management and event listener handling.
.../_buttons/WithdrawButton.tsx, .../_buttons/DepositAndWithdrawButton.tsx Enhanced button functionality through parameter restructuring and hook updates.
.../_cards/ApyPerfomanceCard.tsx, .../_cards/PortfolioCard/index.tsx Improved rendering and variable naming for better clarity and conflict resolution.
.../_forms/BondForm/index.tsx, .../_forms/UnstakeForm.tsx, .../_forms/WithdrawForm.tsx, .../_forms/WithdrawQueueForm.tsx, .../_modals/UnstakeModal.tsx, .../_pages/PageHome.tsx, .../data/hooks/useUserBalance.tsx Streamlined data fetching processes through updated imports and hook usage.
src/data/hooks/useAllStrategiesData.ts, src/data/actions/common/getUserDataAllStrategies.ts, src/data/actions/common/getStrategyData.ts, src/data/tokenConfig.ts, src/data/hooks/useUserBalances.ts Introduced new functionality, added cleanup mechanisms, and refined data management for improved application performance.

Possibly related issues

  • Personalized Strategy Ordering Enhancement #1627: The changes in user balance handling and data fetching mechanisms align with the objectives of the personalized strategy ordering enhancement, potentially enhancing the prioritization of strategies based on user wallet contents.

Poem

Among the code where changes play, 🐇
A rabbit dances through lines each day. 🍃
With tweaks and shifts, a tale unfolds,
Enhancing paths where data molds. 🌊
Through the realms of logic and code's embrace,
The rabbit's touch leaves a subtle trace. ✨


Recent Review Details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits Files that changed from the base of the PR and between 879a123 and 720d4e2.
Files selected for processing (2)
  • src/components/Nav.tsx (2 hunks)
  • src/components/_pages/PageHome.tsx (4 hunks)
Files skipped from review as they are similar to previous changes (1)
  • src/components/_pages/PageHome.tsx

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share
Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger a review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 0

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 24d9b37 and d0c4267.
Files selected for processing (8)
  • src/components/Nav.tsx (2 hunks)
  • src/components/_buttons/WithdrawButton.tsx (2 hunks)
  • src/components/_cards/ApyPerfomanceCard.tsx (1 hunks)
  • src/components/_cards/PortfolioCard/index.tsx (2 hunks)
  • src/components/_layout/LayoutWithSidebar.tsx (1 hunks)
  • src/components/_pages/PageHome.tsx (4 hunks)
  • src/data/hooks/useAllStrategiesData.ts (1 hunks)
  • src/data/hooks/useUserDataAllStrategies.ts (3 hunks)
Additional comments (11)
src/components/_layout/LayoutWithSidebar.tsx (1)
  • 17-21: The introduction of local state management for isConnected using useState and useEffect is a good practice to handle potential asynchronous updates and prevent rendering issues in Next.js. This change ensures that the component's state is correctly updated in response to changes in the user's connection status.
src/data/hooks/useUserDataAllStrategies.ts (1)
  • 63-63: Simplifying the isError assignment to directly use query.isError enhances code readability and maintainability by directly leveraging the properties of the useQuery hook from @tanstack/react-query. This change makes the error handling more straightforward and concise.
src/data/hooks/useAllStrategiesData.ts (1)
  • 43-46: Adding a cleanup function in the useEffect hook to reset error and cellarData states upon component unmounting is an excellent practice for managing component lifecycle and preventing memory leaks. This ensures that the component cleans up after itself, avoiding potential issues with stale state or memory usage.
src/components/_buttons/WithdrawButton.tsx (2)
  • 23-23: Directly destructuring isDeprecated and buttonProps in the function parameters enhances the clarity and readability of the component's prop usage. This approach makes it easier to understand which props are being used and how, promoting better maintainability.
  • 62-64: Replacing props with buttonProps in the button component ensures that all passed props are correctly applied to the SecondaryButton. This change leverages the destructured buttonProps for more explicit and readable prop passing, aligning with best practices for component composition.
src/components/Nav.tsx (1)
  • 44-45: Adding setScrolled(false) in the cleanup function of the useEffect hook for the scroll event listener is a good practice for resetting component state upon unmounting. This ensures that the component's state is correctly managed and does not retain any stale values when the component is no longer in use.
src/components/_cards/ApyPerfomanceCard.tsx (1)
  • 115-121: > 📝 NOTE

This review was outside the diff hunks, and no overlapping diff hunk was found. Original lines [58-58]

Modifying the rendering within the CardHeading component to directly include timeline and apyChartLabel(cellarConfig) without the enclosing <Text> component simplifies the rendering logic and improves the readability of the component. This approach makes the component's structure more straightforward and easier to understand.

src/components/_pages/PageHome.tsx (2)
  • 42-46: The addition of new imports such as add, isBefore from date-fns, useUserDataAllStrategies from data/hooks, useAccount from wagmi, and BigNumber from bignumber.js supports the enhanced functionality introduced in this file. These imports are necessary for the updated sorting logic and handling user data, contributing to the overall objectives of the pull request.
  • 292-333: The revised sorting logic within the useMemo hook, which sorts strategy data based on user-held strategies, newness, rewards, and TVL, is a significant enhancement. This logic effectively prioritizes strategies according to the outlined criteria, improving the user experience by presenting strategies in a personalized and optimized manner. The use of isConnected, userData, and various utility functions from date-fns and BigNumber.js are well-integrated into this logic.
src/components/_cards/PortfolioCard/index.tsx (2)
  • 63-63: Renaming the isConnected variable to connected within the useAccount hook is a thoughtful change to avoid naming conflicts, especially considering the introduction of local state management for the isConnected state. This ensures clarity in variable naming and improves code readability.
  • 75-79: Introducing local state management for the isConnected state using useState and useEffect is a good practice for handling potential asynchronous updates and preventing rendering issues. This change ensures that the component's state is correctly updated in response to changes in the user's connection status, similar to the approach taken in LayoutWithSidebar.tsx.

@otsalex otsalex changed the base branch from staging to main March 28, 2024 16:44
@otsalex otsalex changed the base branch from main to staging March 28, 2024 16:44
@otsalex otsalex force-pushed the Personalized-Strategy-Ordering-Enhancement branch from d0c4267 to 420918b Compare March 28, 2024 16:52
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 0

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 24d9b37 and 420918b.
Files selected for processing (8)
  • src/components/Nav.tsx (2 hunks)
  • src/components/_buttons/WithdrawButton.tsx (2 hunks)
  • src/components/_cards/ApyPerfomanceCard.tsx (1 hunks)
  • src/components/_cards/PortfolioCard/index.tsx (2 hunks)
  • src/components/_layout/LayoutWithSidebar.tsx (1 hunks)
  • src/components/_pages/PageHome.tsx (4 hunks)
  • src/data/hooks/useAllStrategiesData.ts (1 hunks)
  • src/data/hooks/useUserDataAllStrategies.ts (3 hunks)
Files skipped from review as they are similar to previous changes (8)
  • src/components/Nav.tsx
  • src/components/_buttons/WithdrawButton.tsx
  • src/components/_cards/ApyPerfomanceCard.tsx
  • src/components/_cards/PortfolioCard/index.tsx
  • src/components/_layout/LayoutWithSidebar.tsx
  • src/components/_pages/PageHome.tsx
  • src/data/hooks/useAllStrategiesData.ts
  • src/data/hooks/useUserDataAllStrategies.ts

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Review Status

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 420918b and 1cc6105.
Files selected for processing (3)
  • src/components/_pages/PageHome.tsx (4 hunks)
  • src/data/actions/common/getUserDataAllStrategies.ts (3 hunks)
  • src/data/tokenConfig.ts (3 hunks)
Files skipped from review as they are similar to previous changes (1)
  • src/components/_pages/PageHome.tsx
Additional Context Used
Additional comments not posted (5)
src/data/actions/common/getUserDataAllStrategies.ts (3)

8-11: The addition of imports for fetchBalance, getAddress, getAcceptedDepositAssetsByChain, and ResolvedConfig is aligned with the PR's objective to enhance strategy ordering based on various factors including user holdings. Ensure these imported functions and types are used appropriately within the file.


81-96: The loop added to fetch balances for accepted deposit assets is a crucial part of enhancing the strategy ordering based on user holdings. However, there are a few points to consider for improvement:

  1. The use of getAddress to normalize addresses is good practice. However, ensure that token!.address is always defined to avoid potential runtime errors.
  2. The check if (!balance.value.isZero()) before pushing to depositAssetBalances is efficient for filtering out tokens with zero balance. This aligns with the goal of prioritizing strategies based on user holdings.
  3. Consider adding error handling for the fetchBalance call to gracefully handle any failures, ensuring the application's stability.

Consider adding error handling around the fetchBalance call to improve resilience and user experience in case of API failures or network issues.


140-140: The inclusion of depositAssetBalances in the returned data structure supports the PR's objective by potentially influencing strategy ordering based on user holdings. This addition is well-integrated with the rest of the function's return structure.

src/data/tokenConfig.ts (2)

565-565: The addition of WETH, wstETH, and rETH to acceptedARBDepositTokens and the introduction of acceptedOPTDepositTokens are significant for supporting strategy ordering across different chains. This aligns with the PR's objective to enhance user experience by considering various factors, including chain-specific assets.


588-592: The creation of acceptedDepositTokensByChain mapping tokens by chain for Ethereum, Arbitrum, and Optimism is a strategic enhancement. It facilitates the dynamic retrieval of accepted deposit assets based on the user's chain, supporting the PR's goal of personalized strategy ordering.

Comment on lines +620 to +624
export const getAcceptedDepositAssetsByChain = (chainId: string) => {
return acceptedDepositTokensByChain[chainId]
? getTokenConfig(acceptedDepositTokensByChain[chainId], chainId)
: []
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tip

Codebase Verification

The getTokenConfig function's implementation appears to align with the requirements for supporting chain-specific configurations by mapping over a list of token symbols and returning configurations that match both the symbol and the chain. However, there seems to be no test coverage for this function, which is crucial for ensuring its reliability and correctness across different scenarios. It's recommended to add tests for getTokenConfig to verify its functionality and handle potential edge cases.

Analysis chain

The addition of the getAcceptedDepositAssetsByChain function is crucial for retrieving accepted deposit assets by chain. This function enhances the flexibility and scalability of the strategy ordering feature by allowing for chain-specific configurations. Ensure that the getTokenConfig function called within getAcceptedDepositAssetsByChain is correctly implemented and tested for various scenarios to prevent potential issues.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Verify the implementation and test coverage of getTokenConfig function.
rg --type ts "function getTokenConfig"

Length of output: 133



Script:

#!/bin/bash
# Find the implementation details of getTokenConfig
rg --type ts -A 10 "function getTokenConfig" src/data/tokenConfig.ts

# Search for references to getTokenConfig in test files
rg --type ts "getTokenConfig" --glob '*test.ts' --glob '*spec.ts'

Length of output: 336

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Review Status

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 1cc6105 and 530a9f3.
Files selected for processing (1)
  • src/data/actions/common/getUserDataAllStrategies.ts (3 hunks)
Files skipped from review as they are similar to previous changes (1)
  • src/data/actions/common/getUserDataAllStrategies.ts
Additional Context Used

@otsalex otsalex self-assigned this Mar 29, 2024
@otsalex otsalex marked this pull request as ready for review March 29, 2024 17:42
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Review Status

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 530a9f3 and e0710bc.
Files selected for processing (2)
  • src/components/_pages/PageHome.tsx (4 hunks)
  • src/data/actions/common/getUserDataAllStrategies.ts (3 hunks)
Files skipped from review as they are similar to previous changes (2)
  • src/components/_pages/PageHome.tsx
  • src/data/actions/common/getUserDataAllStrategies.ts
Additional Context Used

@zmanian
Copy link
Collaborator

zmanian commented Apr 2, 2024

I think the code also needs to be aware of quantity of the accepted assets in users wallets.

We should probably us the amount of the asset as an input and we probably need to couple that with coingecko prices.

@henrio123 henrio123 marked this pull request as draft April 2, 2024 09:15
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Review Status

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between e0710bc and 0b99b7c.
Files selected for processing (14)
  • src/components/_buttons/DepositAndWithdrawButton.tsx (2 hunks)
  • src/components/_cards/PortfolioCard/index.tsx (3 hunks)
  • src/components/_forms/BondForm/index.tsx (2 hunks)
  • src/components/_forms/UnstakeForm.tsx (2 hunks)
  • src/components/_forms/WithdrawForm.tsx (2 hunks)
  • src/components/_forms/WithdrawQueueForm.tsx (2 hunks)
  • src/components/_modals/UnstakeModal.tsx (2 hunks)
  • src/components/_pages/PageHome.tsx (4 hunks)
  • src/components/_sidebar/PortofolioItem.tsx (2 hunks)
  • src/data/actions/common/getStrategyData.ts (5 hunks)
  • src/data/actions/common/getUserDataAllStrategies.ts (2 hunks)
  • src/data/hooks/useUserBalance.tsx (1 hunks)
  • src/data/hooks/useUserBalances.ts (1 hunks)
  • src/data/hooks/useUserStrategyData.ts (2 hunks)
Files skipped from review due to trivial changes (1)
  • src/data/hooks/useUserBalance.tsx
Files skipped from review as they are similar to previous changes (3)
  • src/components/_cards/PortfolioCard/index.tsx
  • src/components/_pages/PageHome.tsx
  • src/data/actions/common/getUserDataAllStrategies.ts
Additional comments not posted (19)
src/components/_modals/UnstakeModal.tsx (1)

9-9: The update from useUserBalances to useUserBalance is correctly implemented.

src/data/hooks/useUserStrategyData.ts (1)

8-8: The update from useUserBalances to useUserBalance is correctly implemented.

src/components/_sidebar/PortofolioItem.tsx (1)

12-12: The update from useUserBalances to useUserBalance is correctly implemented.

src/components/_forms/UnstakeForm.tsx (1)

25-25: The update from useUserBalances to useUserBalance is correctly implemented.

src/components/_buttons/DepositAndWithdrawButton.tsx (1)

13-13: The update from useUserBalances to useUserBalance is correctly implemented.

src/components/_forms/BondForm/index.tsx (1)

32-32: The update from useUserBalances to useUserBalance is correctly implemented.

src/data/actions/common/getStrategyData.ts (3)

110-110: Consider removing or clarifying the purpose of commented-out code sections related to custom reward APY overrides for better code maintainability and clarity.


149-149: Similarly, clarify or remove the commented-out sections for extra rewards APY calculations to ensure the codebase remains clean and understandable.


96-96: Adding depositTokens to the returned object from getStrategyData aligns with the PR's objectives to enhance strategy ordering and personalization.

src/components/_forms/WithdrawForm.tsx (5)

35-35: Ensure the useUserBalance hook adequately meets the component's requirements for fetching and utilizing user balance data, considering the switch from useUserBalances.


90-90: Consider adding error handling for the useUserBalance hook to manage scenarios where fetching the user's balance might fail.


90-90: Verify that all potential error scenarios, including network errors and smart contract call failures, are adequately handled during the withdrawal operation.


90-90: Ensure that the form validation logic comprehensively covers all necessary scenarios, including edge cases, for user inputs.


90-90: Review the component's UI for responsiveness and accessibility, ensuring it provides a consistent user experience across different devices and screen sizes.

src/components/_forms/WithdrawQueueForm.tsx (5)

31-31: Ensure the useUserBalance hook adequately meets the component's requirements for fetching and utilizing user balance data, considering the switch from useUserBalances.


143-143: Consider adding error handling for the useUserBalance hook to manage scenarios where fetching the user's balance might fail.


143-143: Verify that all potential error scenarios, including network errors and smart contract call failures, are adequately handled during the withdrawal queue operation.


143-143: Ensure that the form validation logic comprehensively covers all necessary scenarios, including edge cases, for user inputs.


143-143: Review the component's UI for responsiveness and accessibility, ensuring it provides a consistent user experience across different devices and screen sizes.

@otsalex otsalex marked this pull request as draft April 9, 2024 17:06
@henrio123 henrio123 marked this pull request as ready for review May 3, 2024 07:01
Signed-off-by: henrio123 <henriots33@gmail.com>
@henrio123 henrio123 merged commit c511043 into staging May 3, 2024
1 of 2 checks passed
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Comment on lines +50 to +52
} catch (error) {
console.error("error", error);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Enhance error logging in fetchBalances for better debugging and user feedback.

-        console.error("error", error);
+        console.error("Failed to fetch user balances:", error);

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
} catch (error) {
console.error("error", error);
}
} catch (error) {
console.error("Failed to fetch user balances:", error);
}

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Comment on lines +47 to +48
window.removeEventListener("scroll", () => {});
setScrolled(false);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incorrect removal of event listener in useEffect cleanup function.

- window.removeEventListener("scroll", () => {});
+ const handleScroll = () => {
+   if (window.scrollY >= 80) {
+     setScrolled(true);
+   } else {
+     setScrolled(false);
+   }
+ };
+ window.addEventListener("scroll", handleScroll);
+ return () => {
+   window.removeEventListener("scroll", handleScroll);
+ };

This change ensures that the same function instance is used for both adding and removing the event listener, preventing potential memory leaks and ensuring proper cleanup.


Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
window.removeEventListener("scroll", () => {});
setScrolled(false);
const handleScroll = () => {
if (window.scrollY >= 80) {
setScrolled(true);
} else {
setScrolled(false);
}
};
window.addEventListener("scroll", handleScroll);
return () => {
window.removeEventListener("scroll", handleScroll);
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants