Медленный ввод текста при очистке с большим количеством содержимого на экране

#reactjs #react-native #expo #textinput

#reactjs #react-native #выставка #ввод текста

Вопрос:

У меня проблема в том, что когда я отправляю спам, вводя текстовый ввод, и нажимаю кнопку, чтобы отправить и очистить текст, он становится лагающим и не сразу очищает текст в текстовом вводе. Это происходит, когда у меня на экране много содержимого (например, текст Lorem Ipsum).

Это проблема для меня, потому что я разрабатываю приложение для чата, и всякий раз, когда журнал чата большой, а пользователи быстро вводят и отправляют сообщение, оно не будет очищено немедленно и все равно останется в TextInput, что является плохим юзабилити. Я попробовал это с помощью ref и контролируемого ввода текста (без разницы).

Вы можете увидеть проблему в моем gif:

введите описание изображения здесь

Вот закуска для expo, чтобы воспроизвести проблему: https://snack.expo.io/s22hVf140

Это мой код:

Мои сообщения:

 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>
  );
};
 

У кого-нибудь есть идея, почему это происходит с большим содержимым на экране?

Комментарии:

1. Рассматривали ли вы возможность использования виртуализированного списка, например FlatList , для отображения каждого элемента чата в журнале? Это должно обеспечить некоторое повышение производительности рендеринга. Вы также должны использовать некоторые инструменты разработки, чтобы помочь определить, что вызывает «большую, чем ожидалось» нагрузку на рендеринг.

2. @98sean98 эта проблема также возникает с FlatList. Я не мог понять, как правильно использовать инструмент разработки профилей, но это действительно весь мой код (см. Раздел, чтобы воспроизвести его)

3. У вас такая же проблема в производстве? Или только в режиме разработки?

4. Я проверил ваш код snack. Сначала я подумал, что ваш рендеринг можно улучшить, приняв во внимание, как работает алгоритм dom diffing от react . Но даже после того, как я добавил an id к каждому новому сообщению перед вставкой в массив, у него есть «задержка», на которую вы ссылаетесь. При ближайшем рассмотрении этого поведения это происходит только тогда, когда вы нажимаете отправить, одновременно вводя другой символ в поле. Таким образом, это означает, что оба submit и (text) => setText(text) были вызваны одновременно. Я пытался найти решение, но пока ничего.

5. @98sean98 да, вы правы. Я «рад», что у вас также есть эта проблема. Это ошибка react native? Поскольку мой код действительно прост, и у меня все еще есть эта проблема…. Спасибо, что тоже нашли решение. 🙂

Ответ №1:

Поскольку submit и onChangeText обратные вызовы запускаются одновременно, когда нажатие клавиши и нажатие кнопки «отправить» происходят одновременно, я отменил submit обратный вызов для запуска с задержкой в 100 мс.

См. раздел «Закуска на выставке«.

Библиотека use-debounce предоставляет элегантное решение для обработки подобных событий пользовательского ввода.

Я также устранил необходимость в a ref , сделав TextInput контролируемым путем передачи value={text} prop.

Что касается того, почему TextInput does not clear() while addMessage() успешно вызывается (без отмены), на данный момент у меня нет объяснения. Хотелось бы знать, может ли кто-нибудь указать.

Не удается решить проблему

После еще нескольких тестов на моем физическом устройстве я иногда наблюдаю нежелательное поведение.

Комментарии:

1. к сожалению, проблема все еще существует, я только что попробовал вашу закуску на своем устройстве, и это то же самое, когда спам набирает и отправляет одновременно. Я думаю, что подход должен заключаться в том, чтобы посмотреть, почему это происходит только с большим контентом. если на экране не так много содержимого, он работает нормально.

2. Хм… Я тестировал на своем iPhone SE 2, запустив клиент expo. Прошел тест одновременности, кажется, все в порядке. Символ появляется при вводе текста, затем отправляется текстовая строка.

3. На моем iPhone XS проблема все еще существует … кроме того, исходя из добавленной вами задержки, теперь у вас небольшая задержка при отправке текста, чтобы он отображался, чего я тоже не хотел бы, поскольку я хочу, чтобы это было быстро.

4. Возможно, единственным способом обойти эту проблему является минимизация задержки до <10 мс (реакция человека обычно находится в диапазоне 100-200 мс, поэтому все, что меньше 50 мс, должно быть едва заметным). Мое наблюдение за Whatsapp, делающим то же самое, также имеет небольшую задержку. Не уверен, совпадает ли эта задержка с тем, что я предложил здесь, но я не думаю, что пользователям будет все равно, если это «не очень заметно».

5. Несмотря на то, что проблема немного улучшилась, приложение теперь выглядит в целом менее гладко. И проблема все еще существует (задержка 10 мс): im2.ezgif.com/tmp/ezgif-2-1d19cf2325fe.gif