recyclerlistview icon indicating copy to clipboard operation
recyclerlistview copied to clipboard

How to update items and best optimization possible?

Open abdullahIsa opened this issue 2 years ago • 2 comments

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;

abdullahIsa avatar Nov 06 '21 15:11 abdullahIsa

did you find a solution to refresh data on the component?

FatmaMahmoud698 avatar Jul 18 '22 13:07 FatmaMahmoud698

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.

abdullahIsa avatar Jul 19 '22 13:07 abdullahIsa