React native pagination duplicationIssue - react-native

I am loading 10 items per page from API and storing the data in redux
suppose I scroll 3 pages so in my redux there are 30 elements 10 elements on page 1 10 on page 2 10 on page 3.
Now I go to the next screen and return to the pagination screen again. My page 1 is again called and in the redux, there is duplication of elements because page 1 elements are already in the redux,
So, should I clear the redux before going to the next screen? So it again starts with page 1

It depends on what you want, so here you go 2 solutions:
1- If you want to keep your data:
Add the pagination logic in your redux code, that way if you reach page 3, in redux the page will be updated to 3, therefore, when you come back to the screen the page will go on from 3 .
A good way to implement the paging logic in redux, is by adding a +1 to the page value in redux state whenever you receive a response:
return {
...state,
data:[...state.data,...data]
page:data.length >0? state.page+1:state.page
}
2- If you are using the same redux for different screens or you want to clear it (which I don't recommend):
Then definitely you will have to clear all your redux data while leaving the screen.
If you have any question, Let me know and good luck!

I suggest you keep another key inside the redux to track the last searched page index.
Initially, it would be something like {lastSearchedPageIndex: 0, items: []}.
When you opened the page for the first time, you would make an API call with the page parameter as 0. You would get a successful response from the API and now the state of redux has to be {lastSearchedPageIndex: 0, items: [SOME_ITEMS_OF_PAGE_0]}.
When you scroll up and reach the page end, you would make another API call. But here you have to make sure that you would only call the API if the page is not searched before. The condition should be if(currentPage > lastSearchedPageIndex) { MAKE_AN_API_CALL_WITH_PAGE_1 } where currentPage is the page number you are searching for. Once you get the response the redux state would be {lastSearchedPageIndex: 1, items:[SOME_ITEMS_FROM_PAGE0, SOME_ITEMS_FROM_PAGE1]}. This would be continued for the remaining pages as well.
Now the paging is done and you are moved to some other screen and come back to the pagination screen. Now the redux state as per your question is {lastSearchedPageIndex: 2, items:[SOME_ITEMS_FROM_PAGE0, SOME_ITEMS_FROM_PAGE1, SOME_ITEMS_FROM_PAGE2]}. You are at the page and scroll to the end of page 0. As we already wrote the guard condition if(currentPage > lastSearchedPageIndex) { MAKE_AN_API_CALL_WITH_PAGE } and according to this, the current page is 1 and lastSearchedPageIndex is 2. So no API call would happen.

Related

When passing data in a stack navigator with lots of screens, will parameters be carried forward from previous screens?

I have a stack navigator in React Native with around 14 screens. When a user clicks next, I use navigation.navigate to go to the next page. I have a lot of parameters and I want to know if I have to explicitly write out each parameter each time the user goes to the next page, or will it carry over from before?
E.g to navigate between screen 1 and screen 2, it passes the value of email:
navigation.navigate("Screen2", {
email: await getData("email"),
});
Then on Screen 2, it navigates to screen 3, not writing email as a parameter:
navigation.navigate("Screen3",
username: uname.trim(),
});
Will screen 3 be able to access/use route.params.email, since it was passed from Screen 1 to Screen 2?
I'm struggling to understand the existing code and thought this might be a solution to the problem I'm facing. The value 'email' is not used in every screen but it is used in both screen 1 and screen 9, so in between this value is not passed between the screens.
No, email will not be available in the nested screens where you didn't pass the email as a param.
I suggest you to use React Context Api, its great for smaller projects for state management.
If your project is large with more than 30 40 screens then you can go with such libraries like Redux and Recoil.
I hope this answer will help you out. Thanks!

useInfiniteQuery refetching all pages on single record mutation

I am using useInfiniteQuery with FlatList in React Native. In one of item in the list there is toggle functionality. I have successfully used useMutation and it works great.
When user scrolls and reach to end I fetch another page. Let's say I have loaded 5 pages i.e. 5 requests on the server. Now I go to the top on the first page and toggle first record using mutation. I used
onSettled: () => queryClient.invalidateQueries(key)
I observed that this causes all pages fetch in background i.e. again 5 requests on the server to fetch all pages which are already there and only for just one record.
so my question is that is it possible to avoid all page request and refetch only the page which was changed. I tried to look in documentation but couldn't find anything helpful on this.

Strategy to update previous screens in react native when new form entries added

I have a use case where I am using stack navigator. I have a homepage where I have some aggregated data and a list which are retrieved from an API.
On clicking on a list item I move to a screen which has more details of that item. There I can add entries for that item. When entries are added using a form, both the homepage as well as the item specific screen need to be updated, which means I need to call the API's again to fetch data. In case no transactions are added I was to avoid this.
What should be the best practice here? should I pass a state variable from homepage and whenever it is updated refresh the screens?
Currently, I am using a willFocus listener, and it makes an API call each time I am on one of these screens. I believe that there can be a better approach than this.

Flutter share bloc between pages

I have a basic flutter app with 2 pages and 1 bloc.
The home page displays a list of users (only 2 attributes)
When a user-item is clicked, a detail page displays all attributes
The user data is fetched using a bloc which emits 2 states
AllUsersLoadedState from the api domain.com/users
UserLoadedState from the api domain.com/users/id
Because both home page and detail page is using the same bloc in their BlocBuilder when I navigate to the detail page and hit the back button, the home page is crashed.
Any way to handle it without writing 2 individual bloc?
If you want to share a BLoC between screens, then you should create the BLoC in such a way that it won't be destroyed while those 2 screens are active.
One way of doing this is to provide the BLoC using the Provider package, or as an InheritedWidget. If you use Provider then on each screen you just ask for the BLoC using Provider.of<MyBloc>(context). You will have to read more about Provider to learn how to use it.
Another way is passing the BLoC as a variable to your widget's constructor.
I figured out what was the issue.
Because both pages were using the same bloc they would rebuild on both states while the intended behavior was for the home page to rebuild only on AllUsersLoadedState and detail page to rebuild only on UserLoadedState.
So when I navigate to the detail page and a UserLoadedState is received the home page didn't know how to handle the state and would crash.
The solution is to use the condition parameter in the bloc builder to skip rebuilding on an unwanted state.

How to detect when there's a new data from API using flat list in React Native?

I am building a react native apps using crna where there's flat list that showing data from API. It's quite like twitter or facebook's status feeds. And I would like to show some badge like this
When there's a new post and to make user aware of new post so they will refresh it.
Could anyone tell me what should I do to make this happen?
Thank you so much.
Not sure if you're using some kind of state management tool like redux, but it would just be a matter of calling the API every so-often and updating the state from there. I'm going to use redux as an example since it's quite popular
You'd prob want state that has the following info:
currentPosts: [] //array of posts that the user already sees
newPosts: [] // array of new posts user can't see until they hit "new posts" button
With redux, you can have a function that gets called every 5 or 10 seconds that checks the API to show where you get new post data from. If there is a new post, add it to the newPosts array. This would update state, and if your component is connected to state, it would update props.
With this logic, you'd be able to determine whether or not you should show the "new posts" button with a simple boolean. If the array is empty, hide it, if it isn't, show the button.
Once the button is clicked, you could update the state so that the newPosts data goes into the currentPosts array and those items will get rendered from there.
Hope this makes sense! There may be quite a lot I'm missing but that's the idea of how it could work. Lemme know if you have any questions