question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Laggy Layout when using Animated.View with entering animations as a child.

See original GitHub issue

I am using entering animations and exiting animations in an

<Animated.View entering={FadeInLeft} exiting={FadeOutLeft}>
          {ActiveSearchType.SERIE === activeSearchType && <SerieResultList />}
</Animated.View>

this component is child of a SafeAreaView from ‘react-native-safe-area-context’ library.

import {
  Pressable,
  SafeAreaView,
  StatusBar,
  StyleSheet,
  Text,
  TextInput,
  View,
  Keyboard,
} from 'react-native';
import {useRecoilValue, useSetRecoilState} from 'recoil';
import {
  videoSearchResult,
  serieSearchResult,
} from '../../Recoil/SearchPage/SearchPage';
import {
  activeCompanySkin,
  hideSearchVideo,
} from '../../Recoil/CompanyDetails/ActiveCompany';
import {searchSeries} from '../../network/API/API_serie';
import {searchVideos} from '../../network/API/API_video';
import {strings} from '../../strings/language';
import Animated, {
  color,
  FadeInLeft,
  FadeInRight,
  FadeOutLeft,
  FadeOutRight,
} from 'react-native-reanimated';
import {useForm, Controller} from 'react-hook-form';
import FontAwesome5 from 'react-native-vector-icons/FontAwesome5';
import BottomSheet, {
  BottomSheetBackdrop,
  BottomSheetFlatList,
  BottomSheetView,
  useBottomSheetDynamicSnapPoints,
  TouchableOpacity,
} from '@gorhom/bottom-sheet';
import {getSearchCategories} from '../../Recoil/SearchPage/SearchPage';
import VideoResultList from '../../components/SearchPageComponents/VideoResulList';
import SerieResultList from '../../components/SearchPageComponents/SerieResultList';

enum ActiveSearchType {
  VIDEO = 'video',
  SERIE = 'serie',
}
const SearchPage = () => {
  const setVideoSearchResult = useSetRecoilState(videoSearchResult);
  const setSerieSearchResult = useSetRecoilState(serieSearchResult);

  const searchCategories = useRecoilValue(getSearchCategories);
  const [selectedCategoryId, setSelectedCategoryId] = useState<number | null>(
    null,
  );
  const [activeSearchType, setActiveSearchType] = useState<ActiveSearchType>(
    ActiveSearchType.SERIE,
  );
  const searchRef: any = React.useRef();
  const Skin = useRecoilValue(activeCompanySkin);
  const Strings = useRecoilValue(strings);
  const {
    _backgroundColor,
    alphaColor,
    fontColor,
    primaryColor,
    buttonTextColor,
  } = Skin;
  //ENIVRONMENT
  const {
    control,
    handleSubmit,
    formState: {errors},
  } = useForm({
    defaultValues: {
      search: '',
    },
  });
  const onSubmit = async ({search}: {search: string}) => {
    console.log(search);
    const searchPromises = await Promise.all([
      searchSeries(
        1,
        search,
        selectedCategoryId !== null ? [selectedCategoryId] : [],
      ),
      searchVideos(
        1,
        search,
        selectedCategoryId !== null ? [selectedCategoryId] : [],
      ),
    ]);
    setSerieSearchResult(searchPromises[0]);
    setVideoSearchResult(searchPromises[1]);
  };
  React.useEffect(() => {
    searchRef?.current.focus();

    const showSubscription = Keyboard.addListener('keyboardDidShow', () => {
      bottomSheetRef?.current?.close();
    });
    return () => {
      showSubscription.remove();
    };
  }, []);
  //BOTTOMSHEET_
  const bottomSheetRef = React.useRef<BottomSheet>(null);
  const data = useMemo(() => searchCategories, []);
  const initialSnapPoints = useMemo(() => ['25%', 'CONTENT_HEIGHT'], []);

  const {
    animatedHandleHeight,
    animatedSnapPoints,
    animatedContentHeight,
    handleContentLayout,
  } = useBottomSheetDynamicSnapPoints(initialSnapPoints);
  const handleSheetChanges = useCallback((index: number) => {
    if (index === 1 || index === 0) {
      Keyboard.dismiss();
    } else {
    }
  }, []);
  const renderBackdrop = useCallback(
    props => (
      <BottomSheetBackdrop
        {...props}
        disappearsOnIndex={-1}
        appearsOnIndex={1}
      />
    ),
    [],
  );
  const SwipeableResultList = () => {
    return (
      <View style={{flex: 1, marginTop: 40}}>
        <Animated.View entering={FadeInLeft} exiting={FadeOutLeft}>
          {ActiveSearchType.SERIE === activeSearchType && <SerieResultList />}
        </Animated.View>
        <Animated.View entering={FadeInRight} exiting={FadeOutRight}>
          {ActiveSearchType.VIDEO === activeSearchType && <VideoResultList />}
        </Animated.View>
      </View>
    );
  };

  return (
    <>
      <StatusBar
        animated={true}
        backgroundColor={_backgroundColor}
        barStyle={fontColor}
      />

      <SafeAreaView
        style={{
          flex: 1,
          backgroundColor: _backgroundColor,
          flexDirection: 'column',
          padding: 15,
        }}>
        <View>
          <Controller
            control={control}
            render={({field: {onChange, onBlur, value}}) => (
              <View
                style={[
                  styles.searchInputContainer,
                  {
                    borderColor: fontColor,
                  },
                ]}>
                <View
                  style={{
                    flex: 4,
                  }}>
                  <TextInput
                    style={[
                      styles.input,
                      {
                        color: fontColor,
                      },
                    ]}
                    returnKeyType={'search'}
                    ref={searchRef}
                    onBlur={onBlur}
                    onChangeText={onChange}
                    value={value}
                    placeholder={Strings.SearchPlaceholder}
                    placeholderTextColor="#A9A9AC"
                    autoCapitalize={'none'}
                    autoCorrect={false}
                    onSubmitEditing={handleSubmit(onSubmit)}
                  />
                </View>
                <View
                  style={{
                    flex: 2,
                    justifyContent: 'center',
                    alignItems: 'center',
                  }}>
                  <Pressable
                    onPress={() => {
                      bottomSheetRef?.current?.expand();
                    }}
                    style={({pressed}) => [
                      {
                        flex: 1,
                        justifyContent: 'center',
                        alignItems: 'center',
                        backgroundColor: _backgroundColor,
                        borderWidth: 2,
                        borderColor: fontColor,
                        borderRadius: 30,
                        width: '100%',
                        height: '100%',
                        opacity: pressed ? 0.7 : 1,
                      },
                    ]}>
                    <View
                      style={{
                        flexDirection: 'row',
                        justifyContent: 'center',
                        alignItems: 'center',
                      }}>
                      <Text
                        style={{
                          color: buttonTextColor,
                          fontSize: 14,
                          marginRight: 5,
                        }}>
                        {Strings.SearchCategory}
                      </Text>
                      <FontAwesome5
                        name={'chevron-down'}
                        solid
                        color={fontColor}
                        size={14}
                      />
                    </View>
                  </Pressable>
                </View>
                <View
                  style={{
                    flex: 1,
                    justifyContent: 'center',
                    alignItems: 'center',
                  }}>
                  <FontAwesome5
                    name={'search'}
                    solid
                    color={fontColor}
                    size={24}
                  />
                </View>
              </View>
            )}
            name="search"
          />
        </View>
        <View
          style={{
            marginTop: 20,

            flexDirection: 'row',
          }}>
          <Pressable
            onPress={() => {
              setActiveSearchType(ActiveSearchType.SERIE);
            }}
            style={{
              flex: 3,
              borderWidth: 2,
              borderColor:
                activeSearchType === ActiveSearchType.SERIE
                  ? primaryColor
                  : fontColor,
              backgroundColor:
                activeSearchType === ActiveSearchType.SERIE
                  ? primaryColor
                  : _backgroundColor,
              borderRadius: 20,
              paddingVertical: 5,
              justifyContent: 'center',
              alignItems: 'center',
            }}>
            <Text
              style={{
                color:
                  activeSearchType === ActiveSearchType.SERIE
                    ? buttonTextColor
                    : fontColor,
                textAlign: 'center',
              }}>
              Serie
            </Text>
          </Pressable>
          <Pressable
            onPress={() => {
              setActiveSearchType(ActiveSearchType.VIDEO);
            }}
            style={{
              flex: 3,
              borderWidth: 2,
              borderColor:
                activeSearchType === ActiveSearchType.VIDEO
                  ? primaryColor
                  : fontColor,
              backgroundColor:
                activeSearchType === ActiveSearchType.VIDEO
                  ? primaryColor
                  : _backgroundColor,
              borderRadius: 20,
              paddingVertical: 5,
              justifyContent: 'center',
              alignItems: 'center',
            }}>
            <Text
              style={{
                color:
                  activeSearchType === ActiveSearchType.VIDEO
                    ? buttonTextColor
                    : fontColor,
                textAlign: 'center',
              }}>
              Video
            </Text>
          </Pressable>
        </View>
        <SwipeableResultList />
        <BottomSheet
          ref={bottomSheetRef}
          index={-1}
          snapPoints={animatedSnapPoints}
          handleHeight={animatedHandleHeight}
          contentHeight={animatedContentHeight}
          enablePanDownToClose={true}
          backdropComponent={renderBackdrop}
          onChange={handleSheetChanges}
          handleStyle={{backgroundColor: fontColor}}
          backgroundStyle={{backgroundColor: fontColor}}>
          <BottomSheetView
            style={{
              flex: 1,
              backgroundColor: _backgroundColor,
              padding: 6,
              margin: 6,
            }}
            onLayout={handleContentLayout}>
            <BottomSheetFlatList
              style={{width: '100%'}}
              data={data}
              keyExtractor={(i: any) => i.name_ml}
              renderItem={({item}: {item: any}) => {
                return (
                  <TouchableOpacity
                    onPress={() => {
                      setSelectedCategoryId(item.id);
                      bottomSheetRef.current?.close();
                    }}>
                    <View
                      style={{
                        flex: 1,
                        backgroundColor: _backgroundColor,
                        padding: 6,
                        margin: 6,
                        flexDirection: 'row',
                      }}>
                      <View
                        style={{
                          flex: 0.5,
                          justifyContent: 'flex-end',
                          alignItems: 'center',
                        }}>
                        <View
                          style={{
                            height: 16,
                            width: 16,
                            borderWidth: 2,
                            borderRadius: 30,
                            borderColor: fontColor,
                            justifyContent: 'center',
                            alignItems: 'center',
                          }}>
                          <View
                            style={{
                              display:
                                selectedCategoryId === item.id
                                  ? 'flex'
                                  : 'none',
                              backgroundColor: fontColor,
                              height: 10,
                              width: 10,
                              borderRadius: 30,
                            }}
                          />
                        </View>
                      </View>
                      <View
                        style={{
                          flex: 5.5,
                          alignItems: 'center',
                        }}>
                        <Text
                          style={{
                            width: '100%',
                            textAlign: 'left',
                            color: fontColor,
                          }}>
                          {item.name}
                        </Text>
                      </View>
                    </View>
                  </TouchableOpacity>
                );
              }}
            />
          </BottomSheetView>
        </BottomSheet>
      </SafeAreaView>
    </>
  );
};
const styles = StyleSheet.create({
  input: {},
  searchInputContainer: {
    borderWidth: 2,
    borderRadius: 30,
    padding: 10,
    flexDirection: 'row',
  },
});
export default SearchPage;

When using animations in entering on any of the views inside the layout is not behaving as expected. The Layout becomes laggy moving up in a non displayed area, under the navigation Header

Expected behavior

Should behave as when i’m not using entering animations.

Actual behavior & steps to reproduce

Layout problems pushing my View and making it laggy

Snack or minimal code example

Package versions

name version
react-native 0.66.4
react-native-reanimated ^2.3.1
NodeJS v16.9.1.
Xcode 13.2.1
Java java version “15” 2020-09-15

Affected platforms

  • Android
  • iOS
  • Web

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:8

github_iconTop GitHub Comments

1reaction
Only-IceSoulcommented, Feb 7, 2022

I think reanimated is tested on a powerful computer and a powerful simulator or cell phone. It is better that you do your animations.

0reactions
iSuedcommented, May 13, 2022

I ned to be more specific. Basically at the end i ended up with custom headers with a specific height:number not percentage or flexbox. So every screen renders a custom header, and this worked quite fine for me.

When using specific height with default header with custom components inside, it used to be glitchy, it seems that default header works fine only when changing little stuff like title, or back button.

For example: I had a logo that i need to show in every page in the center of the header and this was causing a strange behaviour

Read more comments on GitHub >

github_iconTop Results From Across the Web

Why do these constraints seem to lag when animated?
When using layoutIfNeeded() , it should be called on the superview of the view containing the constraints. In my situation, I put the...
Read more >
Reveal or hide a view using animation - Android Developers
There are three common animations to use when showing or hiding a view. You can use the circular reveal animation, a crossfade animation, ......
Read more >
Animated - React Native
Value , hook it up to one or more style attributes of an animated component, and then drive updates via animations using Animated.timing()...
Read more >
CSS and JavaScript animation performance - MDN Web Docs
Browsers are able to optimize rendering flows. In summary, we should always try to create our animations using CSS transitions/animations ...
Read more >
Fixed issues in Animate release - Adobe Support
Animate 2022 (version 22.0.5) · Video export or Publishing takes too long and the output doesn't match with the stage if layer effects...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found