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

[REFACTOR] History data fetching #1698

Merged
merged 6 commits into from
Nov 27, 2024

Conversation

aristidesstaffieri
Copy link
Contributor

@aristidesstaffieri aristidesstaffieri commented Nov 25, 2024

Closes #1672

What
Adds use-get-history hook to fetch history items.
Uses it in AccountHistory to replace in view data fetching.

Why
We've talked about moving to a hook based data fetching pattern for views that need fresh data on every render. Also, account history suffers from a glitchy loading state due to it's current data fetching/loading pattern.

Todo
We should follow up with design tasks for error and empty states for this screen.

Screen.Recording.2024-11-25.at.10.59.25.AM.mov

@aristidesstaffieri aristidesstaffieri self-assigned this Nov 25, 2024
await fetchData();
};
getData();
// eslint-disable-next-line react-hooks/exhaustive-deps
Copy link
Contributor Author

Choose a reason for hiding this comment

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

If we use fetchData as a dep of the useEffect it triggers another load of the data. React officially recommends using an empty array to run effects only on mount.

I think we should remove this lint rule but if we really don't want to we can also use the loading state to step around the extra call, but we won't be able to avoid the extra render.

Copy link
Contributor

@CassioMG CassioMG Nov 25, 2024

Choose a reason for hiding this comment

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

I'm fine using the empty array as useEffect dependency and disabling the lint rule on a case-by-case manner, I think it makes sense for cases where we need to run the code only once on mount 👍

I'm on the fence about removing the lint rule from the project, it could be useful in other cases where it's important to add more deps

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah good point, it has helped me spot missing deps before so maybe it's ok to just step around it for these cases?

Copy link
Contributor

Choose a reason for hiding this comment

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

+1

Copy link
Contributor

Choose a reason for hiding this comment

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

Agreed - let's keep the lint rule and just disable when we explicitly just want to run on mount

@aristidesstaffieri aristidesstaffieri requested a review from a team November 25, 2024 18:00
const showLoader =
getHistoryState.state === RequestState.IDLE ||
getHistoryState.state === RequestState.LOADING;
const hasEmptyHistory = !showLoader || !getHistoryState.data;
Copy link
Contributor

Choose a reason for hiding this comment

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

should we be checking for data.length here?
do we really need to check the showLoader value here?

e.g.:
const hasEmptyHistory = !getHistoryState?.data?.length;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

we can't rely on the history length alone because then we would show this message during loading or idle states. I believe the correct logic is "show this when data is not loading and there is no history".

Copy link
Contributor

Choose a reason for hiding this comment

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

got it, so maybe something like this?
const hasEmptyHistory = !showLoader && !getHistoryState?.data?.length;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah good call to cover the empty array case as well, updating to this!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

actually since you suggested we pull out the loading render branch, it did make it easier to use your original suggestions. Updated in c1612f5

@JakeUrban
Copy link
Contributor

We should follow up with design tasks for error and empty states for this screen.

What do these cases look like now?

return <TransactionDetail {...detailViewProps} />;
}

return showLoader ? (
Copy link
Contributor

Choose a reason for hiding this comment

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

I think it's totally up to you but just leaving a little suggestion here. I personally think avoiding the ternary operator for big chunks of code reads a little bit better. E.g.:

if (isDetailViewShowing) {
  return <TransactionDetail {...detailViewProps} />;
}

if (showLoader) {
  return <Loading />;
}

return <View.Content>
   ...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

oh yeah good call, I pulled out isDetailViewShowing but not sure why I didn't pull out the loading state. I'll make that change. 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

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

updated in 8812240

}
};

function useGetHistory(publicKey: string, networkDetails: NetworkDetails) {
Copy link
Contributor

Choose a reason for hiding this comment

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

thanks for implementing this!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's a little different than the example we discussed in the issue but this seemed easy to work with, open to any feedback on this pattern!

@aristidesstaffieri
Copy link
Contributor Author

We should follow up with design tasks for error and empty states for this screen.

What do these cases look like now?

The empty case just prints "No transactions to show" and an error to fetch history results in an empty history pane. I don't think we've ever had UI state for errors on this screen.

@@ -0,0 +1,85 @@
import { useReducer } from "react";
Copy link
Contributor

Choose a reason for hiding this comment

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

NIT: can you call this file useGetHistory.tsx to conform to the naming convention in the rest of the repo?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

whoops old habit, renamed in be39fcd

isHideDustEnabled,
]);

const showLoader =
Copy link
Contributor

Choose a reason for hiding this comment

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

NIT: let's call this isLoaderShowing to follow code convention

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yup, renamed in 68003d3

@aristidesstaffieri aristidesstaffieri merged commit 0be856e into release/5.26.0 Nov 27, 2024
3 checks passed
@aristidesstaffieri aristidesstaffieri deleted the refactor/history-data-flow branch November 27, 2024 17:35
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.

4 participants