TextInput 清除速度慢,屏幕上有很多内容

Posted

技术标签:

【中文标题】TextInput 清除速度慢,屏幕上有很多内容【英文标题】:TextInput slow on clear with a lot of content on screen 【发布时间】:2021-04-11 18:33:53 【问题描述】:

我有一个问题,当我在 TextInput 中输入垃圾邮件并单击按钮以提交并清除文本时,它会变得迟钝,并且不会立即清除 TextInput 中的文本。 当我在屏幕中有大量内容(例如 Lorem Ipsum 文本)时,就会发生这种情况。

这对我来说是个问题,因为我正在开发一个聊天应用程序,每当聊天日志很大并且用户快速输入和提交消息时,它不会立即被清除,并且仍会保留在 TextInput 中,即可用性差。我用 ref 和受控的 TextInput 尝试过(没有区别)。

您可以在我的 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>
  );
;

我的文本输入:

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

有人知道为什么屏幕上的大内容会发生这种情况吗?

【问题讨论】:

您是否考虑过使用像FlatList 这样的虚拟化列表来呈现日志中的每个聊天项目?这应该会提供一些渲染性能提升。您还应该使用一些开发工具来帮助确定导致“超出预期”的渲染负载的原因。 @98sean98 这个问题也发生在 FlatList 上。我不知道如何正确使用配置文件开发工具,但这确实是我的全部代码(请参阅小吃以重现它) 您在生产中是否有同样的问题?还是仅在开发模式下? 我已经查看了您的零食代码。起初我认为您的渲染可以通过考虑how react's dom diffing algorithm works 来改进。但是,即使在插入数组之前,我已经为每条新消息添加了id,它仍然具有您所指的“滞后”。在仔细检查该行为后,它只会在您点击提交同时在框中输入另一个字符时发生。这意味着submit(text) =&gt; setText(text) 被同时调用。我试图想出一个解决方案,但还没有。 @98sean98 是的,你是对的。我很“高兴”你也有这个问题。它是反应原生的错误吗?因为我的代码非常简单,我仍然有这个问题....也感谢您找到解决方案。 :) 【参考方案1】:

由于submitonChangeText 回调在同时发生键盘敲击和单击“提交”按钮时被同时触发,所以我已对submit 回调进行去抖动处理,以延迟 100 毫秒运行。

见expo snack。

use-debounce 库提供了一个优雅的解决方案来处理此类用户输入事件。

我还通过传递 value=text 属性来控制 TextInput,从而消除了对 ref 的需求。

至于为什么TextInput 没有clear()addMessage() 被成功调用(没有去抖动),我目前没有解释。很想知道是否有人可以指出。

未能解决问题

在我的物理设备上进行了几次测试后,我偶尔会观察到不需要的行为。

【讨论】:

不幸的是,问题仍然存在,我刚刚在我的设备上尝试了您的零食,并且在垃圾邮件同时输入和提交时,它是相同的。我认为方法应该是看看为什么它只发生在大内容上。如果屏幕上没有太多内容,它可以正常工作。 嗯...我在运行 expo 客户端的 iPhone SE 2 上进行了测试。进行了同时性测试,似乎还可以。字符出现在文本输入中,然后提交文本字符串。 在我的 iPhone XS 上,问题仍然存在......此外,根据您添加的延迟,您现在在提交文本时会有一点延迟,以便显示,这也不是我会想要,因为我希望它快。 也许将延迟最小化到 尽管问题稍微好一些,但应用程序现在总体感觉不太流畅。问题仍然存在(延迟 10 毫秒):im2.ezgif.com/tmp/ezgif-2-1d19cf2325fe.gif

以上是关于TextInput 清除速度慢,屏幕上有很多内容的主要内容,如果未能解决你的问题,请参考以下文章

在关注textinput时,保持textinput和键盘的小差距

ScrollView 在 React Native 中删除 TextInput 键盘

为啥直接内存“数组”的清除速度比通常的 Java 数组慢?

如何清除 SQL 缓存

手机点击延迟怎么办

在不关闭键盘的情况下使用 TouchableOpacity 清除 Textinput?