React native:TextInput中的竞争条件

问题描述 投票:0回答:2

我遇到了TextInput的问题,该问题从用户那里获取输入,还有一个按钮,它在TextInput中发送消息并清除了输入。因此,总体流程为:

  1. 用户输入到TextInput中的类型
  2. 在某些时候,用户按下Button(aka。TouchableOpacity)
  3. 将文本从TextInput存储到临时缓冲区,然后清除TextInput。
  4. 通过api发送文本。

代码看起来像:

    {/* Message Input */}
    <TextInput
      style={styles.messageInput}
      multiline
      onChangeText={text => {
        setMessage(text);
      }}
      value={message}
    />

    {/* Send Button */}
    <Button
      title={"Send"}
      onPress={() => {
        const msg = message
        onSendMessage(msg);
        setMessage("");
      }}
      disabled={false}
      style={styles.sendButton}
    />

并且我的问题出现在用户点击发送按钮后过早键入时。如果用户决定键入得太早,则不会清除TextInput。我认为这是因为:

  1. 用户轻按发送=>使渲染入队,因为在Button的onPress中,通过setMessage(“”)改变了消息状态
  2. 用户类型过早=>使渲染入队,因为消息由TextInput中的onChangeText处理程序更改。问题是尚未真正处理先前状态的setMessage。因此,此呈现器与消息的先前值(也就是消息被设置为“”之前的值)一起排队。

我尝试了Promise,useEffect和useRef,但没有什么能真正解决此问题。如果有人知道如何解决此问题,请告诉我。预先谢谢你。

react-native react-hooks race-condition react-native-textinput
2个回答
0
投票
在此用例中,

您应使用回叫承诺异步/等待。我建议您使用Promise

onSendMessage = msg => {
    axios
      .post("/your-url", {
        msg
      })
      .then(function(response) {
        console.log(response);
        // ! You can clear the message here !
        setMessage("");
        // OR
        return new Promise(() => resolve(msg));
      })
      .catch(function(error) {
        console.log(error);
      });
  };

类似的东西。使用的选择是您的:)


0
投票

useState挂钩是异步的,不会立即反映和更新,但会触发重新渲染。因此,您不应将此值存储在这样的常量中:const msg = message

我将创建一个异步函数,将输入发送到api。 (奖金:添加加载状态以通过禁用提交按钮向用户提供反馈)

const [isLoading, setIsLoading] = useState(false);

onSubmit = async () => {
  setIsLoading(true);
  const response = await fetch('url/action', settings);
  if(response){
    setIsLoading(false);
    return response.json();
  }
}
    <TextInput
      style={styles.messageInput}
      multiline
      onChangeText={text => {
        setMessage(text);
      }}
      value={message}
    />

    <Button
      title={"Send"}
      onPress={() => onSubmit()}
      disabled={isLoading}
      style={styles.sendButton}
    />
© www.soinside.com 2019 - 2024. All rights reserved.