react-native-portalize icon indicating copy to clipboard operation
react-native-portalize copied to clipboard

TextInput inside a portal is buggy

Open eloisp opened this issue 5 years ago • 12 comments

Hi,

I use this plugin to have a beautiful shadow (all screen) behind a bottom sheet (https://github.com/osdnk/react-native-reanimated-bottom-sheet). I have some textinput inside, but the cursor is buggy they are in the Portal.

This is the exact same issue than him : https://github.com/callstack/react-native-paper/issues/1668

He found a hack but it seems... terrible.

Any idea to correct the problem? Thank's !

eloisp avatar Aug 04 '20 16:08 eloisp

Hi,

Indeed this issue is very weird. Did you try with react-native-web or react-native?

I tried it with the following:

npx create-react-native-app test
cd test
yarn start
yarn ios # other tab

App.js

import React, { useState } from 'react';
import { TextInput } from 'react-native';
import { Portal, Host } from 'react-native-portalize';

export default () => {
  const [data, setData] = useState('foo');

  return (
    <Host>
      <Portal>
        <TextInput style={{ top: 200 }} value={data} onChangeText={setData} />
      </Portal>
    </Host>
  );
};

and it works as expected. (Also, you have to use Host component and not Provider when using react-native-portalize)

Have you tried using TextInput from react-native directly instead of react-native-paper?

jeremybarbet avatar Aug 07 '20 13:08 jeremybarbet

this issue still exists.

raifemre avatar Aug 12 '20 15:08 raifemre

I changed my plan for my app so I no more use Portalize (use a modal instead). But for those who still have this issue, this fix it :

export const TextInputInAPortal = (props) => {
  const [value, setValue] = useState(props.value)

  useEffect(() => {
    if(value !== props.value)
      setValue(props.value)
  }, [props.value])

  const onChangeText = (text: string) => {
    setValue(text)
    props.onChangeText(text)
  }
  return React.createElement(TextInput, {...props, value, onChangeText})
}

Thank's @jeremybarbet for your work :)

eloisp avatar Aug 13 '20 06:08 eloisp

I confirm the bug. I am using TextInput from react-native

AlexSmirnov9107 avatar Nov 11 '20 16:11 AlexSmirnov9107

This issue also affect when input with Chinese languages. The workaround cannot solve.

Here is the demo: https://snack.expo.io/@hkhermanho/textinput-with-cjk RPReplay_Final1607016357_320

There is no problem when both TextInput are placed without Portal. RPReplay_Final1607016421_320

hermanho avatar Dec 03 '20 17:12 hermanho

I'm having the same issue

fermmm avatar Jan 14 '21 04:01 fermmm

The issue occurs when you use portal in component, which control input by state. As workaround, i made HOC for portal:

import React, { FC } from 'react'
import { Portal } from 'react-native-portalize'

export const withPortal = <P,>(Component: FC<P>) => (props: P) => (
  <Portal>
    <Component {...props} />
  </Portal>
)

Then, i can use it like this:

export default withPortal(ComponentWithInput)

If component, which makes textinput value updates, is inside portal it works as it should

zombie6888 avatar Jan 18 '21 00:01 zombie6888

maybe https://github.com/gorhom/react-native-portal could solve your problem ?

younes0 avatar Jul 10 '21 19:07 younes0

try this:

import React, { useState } from 'react';
import { TextInput } from 'react-native';
import { Portal, Host } from 'react-native-portalize';

export default () => {
  const [data, setData] = useState('foo');

  return (
    <Host>
      <Portal>
        <TextInput style={{ top: 200 }} defaultValue={data} onChangeText={setData} />
      </Portal>
    </Host>
  );
};

wolfag avatar Jan 25 '22 02:01 wolfag

Still encounter the same issue when using react-native-modalize

The text input glitch like @hermanho provided demo video. This issue occur while passing the state to Modalize component. Any suggestion is appreciated and thank you in advanced!

import { Portal } from 'react-native-portalize';

const QuickInstallation: FC<PrivateStackNavProps<'QuickInstallation'>> = ({ route, navigation }) => {
  const roomListModalRef = React.useRef<Modalize>();
  const [searchRoom, setSearchRoom] = useState('');

  const openRoomListModal = () => {
    roomListModalRef.current?.open();
  };

  const closeRoomListModal = () => {
    roomListModalRef.current?.close();
  };

  const selectRoomOption = ({ id, name }: RoomDto) => {
    setSelectedRoom({ id, name });
    closeRoomListModal();
  };

  return (
    <Layout>
      <Portal>
        <Modalize
          ref={roomListModalRef}
          modalHeight={modalHeight}
          tapGestureEnabled={false}
          HeaderComponent={
            <ModalHeader title="安裝教室" onPressCloseButton={closeRoomListModal}>
              <SearchBar placeholder="搜尋教室名稱" onChangeText={(value) => setSearchRoom(value)} value={searchRoom} />
            </ModalHeader>
          }
        />
      </Portal>
    </Layout>
  );
};

JaynPan avatar Feb 24 '22 09:02 JaynPan

This is still an issue. When selecting an input that opens the keyboard outside the modal, then selecting an input inside the portal that opens the keyboard and you close the keyboard, the whole layout gets screwed up.

bombillazo avatar Aug 24 '22 06:08 bombillazo

if you still have an problem with multiline prop use defaultValue={text} instead of value={text}

mertcankose avatar Sep 25 '23 13:09 mertcankose

OMG @mertcankose how was that so simple? Thank you, fixed my problem.

convurt avatar Oct 04 '23 21:10 convurt