1

我遇到了 TextInput 的问题,它从用户那里获取输入,以及一个在 TextInput 中发送消息并清除输入的按钮。所以整体流程是:

  1. 用户输入 TextInput
  2. 在某些时候,用户按下按钮(又名 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. 用户点击发送 => 排队渲染,因为消息状态由按钮的 onPress 中的 setMessage("") 更改
  2. 用户输入太快 => 排队渲染,因为 TextInput 中的 onChangeText 处理程序更改了消息。问题是来自先前状态的 setMessage 尚未真正处理。因此,此渲染与消息的先前值(又名消息设置为 "" 之前的值)一起排队。

我尝试了 Promise、useEffect 和 useRef,但没有真正解决这个问题。如果有人知道如何解决这个问题,请告诉我。先感谢您。

4

2 回答 2

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}
    />
于 2019-11-14T15:17:41.427 回答
0

对于这个用例,您应该使用CallbackPromiseAsync/Await 。我建议你使用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);
      });
  };

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

于 2019-11-14T14:57:46.630 回答