TextInput slow on clear with a lot of content on screen

Viewed 263

I have an issue that when I spam typing in a TextInput and click a button on to submit and clear the text it becomes laggy and it doesn't clear the text in the TextInput right away. This happens when I have a lot of content within the Screen (like Lorem Ipsum text).

This is a problem for me, because I am developing a chat app and whenever the chat log is large and the users types and submits the message fast it won't get cleared immediately and will still remain in the TextInput, which is bad usability. I tried it with ref and controlled TextInput (no difference).

You can see the issue in my gif:

enter image description here

Here is a snack for expo to reproduce the issue: https://snack.expo.io/s22hVf140

This is my code:

MyMessages:

const MyMessages = () => {
  const [messages, setMessages] = useState([]);

  const addMessage = (text) => {
    const arr = [text, ...messages];
    setMessages(arr);
  };

  return (
    <View>
      <MyTextInput addMessage={addMessage}></MyTextInput>
      {messages.map((msg, i) => {
        return <Text key={i}>{msg}</Text>;
      })}
      <Text>
        Lorem ipsum.......
      </Text>
    </View>
  );
};

MyTextInput:

const MyTextInput = ({ addMessage }) => {
  const [text, setText] = useState("");
  const myRef = useRef();
  const submit = () => {
    myRef.current.clear();
    addMessage(text);
  };

  return (
    <View>
      <TextInput
        ref={myRef}
        style={{
          width: "100%",
          height: 50,
          backgroundColor: "lightgrey",
          marginTop: 50,
        }}
        onChangeText={(text) => setText(text)}
      ></TextInput>
      <Button title="submit" onPress={submit}></Button>
    </View>
  );
};

Anyone has an idea why this happens with large content on the screen?

1 Answers

Since submit and onChangeText callbacks are fired simultaneously when a keyboard stroke and clicking the "submit" button happen together, I have debounced the submit callback to run with a 100ms delay.

See expo snack.

The use-debounce library provides an elegant solution to handle user input events like these.

I have also removed the need for a ref by making TextInput controlled through passing value={text} prop.

As to why the TextInput does not clear() while addMessage() is successfully called (without the debouncing), I do not have an explanation at the moment. Would love to know if anyone could point out though.

Fails to solve issue

After a couple more tests on my physical device, I'm occasionally observing the unwanted behaviour.
Related