Skip to content

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

@maticDevelo

Description

@maticDevelo

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.

multiline.error.mov

Reproduction steps

  • Create BottomSheetModal component
  • Import it in screen component
  • pass ref into BottomSheetModal and call it using a button (ref.current?.present())
    -type into input text that has multiline true

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinginvalidThis doesn't seem right

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions