recyclerlistview
recyclerlistview copied to clipboard
How to update items and best optimization possible?
Hello thanks for this, decided to give it a try as flatlist wasn't doing things as properly as I want, I would like to ask how can I optimize this code, and as you can see each item gets the propsData and that contains either key values or functions so that if any item is clicked the parent component can get what was clicked but in code below how do I make when an item is clicked and the Data is updated by index at the parent level how do I update that item into DataProvider without re-rendering everything and also how can I prevent unnecessary renderings, thanks.
CODE
import React, {memo, useMemo, useRef, useState, useEffect, useCallback,} from 'react';
import {View, Text, Dimensions, RefreshControl} from 'react-native';
import {RecyclerListView, DataProvider, LayoutProvider} from 'recyclerlistview';
import {OptimizedHeavyScreen} from 'react-navigation-heavy-screen';
import * as Animatable from 'react-native-animatable';
import LottieView from 'lottie-react-native';
import EachItems from './eachLists';
const ViewTypes = {
FULL: 0,
HALF_LEFT: 1,
HALF_RIGHT: 2,
};
let {width} = Dimensions.get('window');
const SearchRenderer = memo(
({
dataAll,
propsData = {},
setLoadMore = () => null,
showIsLoadingMore = false,
bottomComponentProp = null,
floatingView = null,
searchedFoundMessage = '',
allowLoadMore = true,
onPressItemCallBack = () => null,
enableRefreshing = false,
isRefreshing = () => null,
refreshing = false,
}) => {
const [data, setData] = useState([]);
const [isLoadingMore, setIsLoadingMore] = useState(false);
const [isLoadingMoreId, setisLoadingMoreId] = useState(null);
const _layoutProvider = useRef(layoutMaker()).current;
const [message, setMessage] = useState('');
const listView = useRef();
const dataProvider = useMemo(() => dataProviderMaker(data), [data]);
useEffect(() => {
if (dataAll === undefined) {
setData([]);
} else {
setData(dataAll);
}
loaderChecker();
setMessage(searchedFoundMessage);
}, [dataAll, showIsLoadingMore, searchedFoundMessage]);
const onRefresh = useCallback(() => {
isRefreshing(true);
}, []);
const loadMore = () => {
if (allowLoadMore === true) {
setLoadMore(true);
setIsLoadingMore(true);
}
};
const loaderChecker = () => {
if (isLoadingMoreId) {
clearTimeout(isLoadingMoreId);
}
setIsLoadingMore(true);
const idTimout = setTimeout(() => {
setIsLoadingMore(false);
}, 3000);
setisLoadingMoreId(idTimout);
};
return (
<OptimizedHeavyScreen style={{flex: 1}}>
<View style={{flex: 1}}>
{!data.length ? (
<View>
<RenderFooter
loading={isLoadingMore}
message={message}
style={{marginTop: 20, marginBottom: 5}}
/>
{bottomComponentProp}
</View>
) : (
<RecyclerListView
ref={listView}
renderFooter={() => (
<RenderFooter
loading={isLoadingMore}
message={message}
style={{marginTop: 5, marginBottom: 20}}
/>
)}
onEndReached={() => loadMore()}
onEndReachedThreshold={1}
layoutProvider={_layoutProvider}
dataProvider={dataProvider}
rowRenderer={(type, data) =>
rowRenderer(type, data, {
...propsData,
onPressItemRadioButtonCallBack: onPressItemCallBack,
onPressItemCallBack: onPressItemCallBack,
})
}
contentContainerStyle={{paddingBottom: 150}}
scrollViewProps={{
refreshControl: (
<RefreshControl
refreshing={refreshing}
enabled={enableRefreshing}
onRefresh={onRefresh}
/>
),
}}
/>
)}
{floatingView}
</View>
</OptimizedHeavyScreen>
);
},
);
const layoutMaker = () =>
new LayoutProvider(
index => {
return ViewTypes.FULL;
},
(type, dim) => {
switch (type) {
case ViewTypes.HALF_LEFT:
dim.width = width / 2;
dim.height = 160;
break;
case ViewTypes.HALF_RIGHT:
dim.width = width / 2 - 0.001;
dim.height = 160;
break;
case ViewTypes.FULL:
dim.width = width;
dim.height = 80;
break;
default:
dim.width = 0;
dim.height = 0;
}
},
);
const rowRenderer = (type, data, propsData) => {
if (data == null || data === undefined) return null;
switch (type) {
case ViewTypes.HALF_LEFT:
return null;
case ViewTypes.HALF_RIGHT:
return null;
case ViewTypes.FULL:
return <EachItems item={data} propsData={propsData} />;
default:
return null;
}
};
const RenderFooter = ({loading, message, style = {}}) => (
<View style={style}>
{message !== '' && (
<Animatable.View animation="zoomIn">
<Text style={{color: 'grey', alignSelf: 'center'}}>{message}</Text>
</Animatable.View>
)}
{loading && (
<Animatable.View animation="zoomIn">
<LottieView
source={require('../../assets/62116-loading.json')}
autoPlay
loop
style={{
height: 59,
width: 59,
alignSelf: 'center',
}}
/>
</Animatable.View>
)}
</View>
);
const dataProviderMaker = data =>
new DataProvider((r1, r2) => {
return r1 !== r2;
}).cloneWithRows(data);
export default SearchRenderer;
did you find a solution to refresh data on the component?
did you find a solution to refresh data on the component?
Hello nope not really, you can check this link on how i was using it might be helpful. https://github.com/EnTechCS/MessagesRenderRecyclerListView/blob/main/messagesRenderRecyclerListView.js
Now i am testing and trying out https://github.com/Shopify/flash-list , https://shopify.github.io/flash-list its basically Recyclerlistview + Flatlist, check it out might be helpful.