gorhom / react-native-bottom-sheet

A performant interactive bottom sheet with fully configurable options 🚀
https://gorhom.dev/react-native-bottom-sheet/
MIT License
6.94k stars 756 forks source link

[Bug]: InputText Multiline prop enabled causes infinite re-renders of state. #1999

Closed maticDevelo closed 3 hours ago

maticDevelo commented 3 hours ago

Version

v5

Reanimated Version

v3

Gesture Handler Version

v2

Platforms

iOS

What happened?

Code below is my Component of BottomSheetModal using styled components. When typing in TextInput that has multiline={true} it start infinite loop or re-renders between current and last state. See in video. Same bug appears using BottomSheetTextInput.

https://github.com/user-attachments/assets/fef579ae-6396-4f66-9028-b5ff095b2d5c

Reproduction steps

Reproduction sample

import { View } from 'react-native';
import styled from 'styled-components';
import {
  BottomSheetModal,
  BottomSheetScrollView,
} from '@gorhom/bottom-sheet';
import { theme } from '@/styles';

export const StyledBottomSheetModal = styled(BottomSheetModal).attrs({
  backgroundStyle: {
    borderTopLeftRadius: 32,
    borderTopRightRadius: 32,
  },
  handleStyle: {
    position: 'absolute',
    width: '100%',
    height: 76,
    borderTopLeftRadius: 32,
    borderTopRightRadius: 32,
    pointerEvents: 'none',
  },
  handleIndicatorStyle: {
    backgroundColor: theme.colors.labelBlack10,
  },
})``;

export const BottomDrawerModalHeader = styled(View)`
  padding: 32px 20px 0;
`;

export const StyledBottomSheetScrollView = styled(
  BottomSheetScrollView,
).attrs({
  contentContainerStyle: {
    flex: 0,
    flexGrow: 1,
  },
})`
  padding: 0 20px 50px;
`;

type BottomDrawerProps = {
  header?: ReactNode;
  children: ReactNode;
  onChange?: () => void;
  onClose?: () => void;
  snapPoints?: string[];
};

const BottomDrawerModal = forwardRef<BottomSheetModal, BottomDrawerProps>(
  (
    {
      header,
      children,
      onChange,
      onClose,
      snapPoints = ['30%', '50%', '70%', '99%'],
    },
    ref,
  ) => {
    const snapPointsMemo = useMemo(() => snapPoints, []);
    const [text, setText] = useState<string>('');

    const handleSheetChanges = useCallback((index: number) => {
      onChange?.();

      if (index === -1) {
        if (ref && 'current' in ref && ref.current) {
          ref.current.close();
          onClose?.();
        }
      }
    }, []);

    const renderBackdrop = useCallback(
      (
        props: JSX.IntrinsicAttributes & BottomSheetDefaultBackdropProps,
      ) => (
        <BottomSheetBackdrop
          {...props}
          appearsOnIndex={0}
          disappearsOnIndex={-1}
          style={[
            props.style,
            { backgroundColor: theme.colors.overlay40Opacity },
          ]}
        />
      ),
      [],
    );

    return (
      <StyledBottomSheetModal
        ref={ref}
        snapPoints={snapPointsMemo}
        enablePanDownToClose
        index={0}
        backdropComponent={renderBackdrop}
        onChange={handleSheetChanges}
      >
        <View style={{ flex: 1 }}>
          <BottomDrawerModalHeader>{header}</BottomDrawerModalHeader>
          <StyledBottomSheetScrollView pointerEvents='box-none'>
            <TextInput
              multiline={true}
              value={text}
              onChangeText={setText}
            />
            {children}
          </StyledBottomSheetScrollView>
        </View>
      </StyledBottomSheetModal>
    );
  },
);

BottomDrawerModal.displayName = 'BottomDrawerModal';

export default BottomDrawerModal;

Relevant log output

LOG  state Acwwacasa
 LOG  state Acwwacas
 LOG  state Acwwacasa
 LOG  state Acwwacas
 LOG  state Acwwacasa
 LOG  state Acwwacas
 LOG  state Acwwacasa
 LOG  state Acwwacas
 LOG  state Acwwacasa
 LOG  state Acwwacas
 LOG  state Acwwacasa
 LOG  state Acwwacas
 LOG  state Acwwacasa
 LOG  state Acwwacas
 LOG  state Acwwacasa
 LOG  state Acwwacas
 LOG  state Acwwacasa
 LOG  state Acwwacas
 LOG  state Acwwacasa
 LOG  state Acwwacas
 LOG  state Acwwacasa
 LOG  state Acwwacas
 LOG  state Acwwacasa
 LOG  state Acwwacas
 LOG  state Acwwacasa
 LOG  state Acwwacas
github-actions[bot] commented 3 hours ago

Hello @maticDevelo :wave:, this issue is being automatically closed and locked because it does not follow the issue template.