我遇到了TextInput的问题,它从用户那里获取输入,以及一个在TextInput中发送消息并清除输入的按钮。因此,总体流程为:
- 用户在TextInput中键入
- 在某个时刻,用户按下按钮(又名TouchableOpacity(
- 将文本从TextInput存储到临时缓冲区,然后清除TextInput
- 通过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。我认为这是因为:
- 用户点击send=>排队渲染,因为消息状态在Button的onPress中通过setMessage("(更改
- 用户类型太快=>排队呈现,因为消息由TextInput中的onChangeText处理程序更改。问题是以前状态的setMessage还没有得到真正的处理。因此,此呈现使用消息的前一个值(也就是消息设置为"之前的值(进行排队
我尝试了Promise、useEffect和useRef,但没有真正解决这个问题。如果有人知道如何克服这个问题,请告诉我。提前谢谢。
对于此用例,您应该使用Callback或Promise,或Async/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);
});
};
类似的东西。使用方式由您选择:(
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}
/>