reactjs - 第一次调用函数后,应用程序中的状态不会改变。需要两次尝试才能改变
问题描述
我有如下代码。我的应用程序从 API 获取加密密码,并在解密后将其复制到剪贴板几秒钟。解密发生在我按下Copy Password
按钮的那一刻。但是,当我按下按钮 1 时,我的密码没有被复制到剪贴板,这意味着由于某种原因状态password
没有改变。只有在我短时间按 2 次后,密码才会被复制到剪贴板。这背后可能是什么原因?我已经测试了很多案例"dec_password"
,decPassword
在我看来,实际问题发生在组件中,而不是在上下文中。
零件:
import React, { useContext, useEffect } from "react";
import { View, StyleSheet, Text, Clipboard } from "react-native";
import { Context as PasswdDetailContext } from "../context/PasswdDetailContext";
import { Button, Input } from "react-native-elements";
import { decryptRecord } from "../components/Crypto";
import { Context as AuthContext } from "../context/AuthContext";
import { NavigationEvents } from "react-navigation";
import Spacer from "../components/Spacer";
const PasswdDetailScreen = ({ navigation }) => {
const {
state: { username, password, domain, description },
decData,
decPassword,
resetPassword,
reset,
} = useContext(PasswdDetailContext);
const {
state: { secretKey },
} = useContext(AuthContext);
const id = navigation.getParam("id");
const clipboardPasswd = () => {
Clipboard.setString(password);
setTimeout(() => {
Clipboard.setString("");
resetPassword();
}, 10000);
};
return (
<>
<NavigationEvents
onWillFocus={() => decData({ id, secretKey })}
onDidBlur={() => {}}
/>
<Text>Username: {username}</Text>
<Text>Password: {password}</Text>
<Text>Description: {description}</Text>
<Button
title="Copy Password"
onPress={() => decPassword({ id, secretKey })}
onPressIn={() => clipboardPasswd()}
/>
<Input label="Password" />
</>
);
};
const styles = StyleSheet.create({});
export default PasswdDetailScreen;
语境:
import createDataContext from "./createDataContext";
import trackerApi from "../api/tracker";
import { AsyncStorage } from "react-native";
import { decryptRecord } from "../components/Crypto";
const passwdDetailReducer = (state, action) => {
switch (action.type) {
case "dec_username":
return { ...state, username: action.payload };
case "dec_password":
return { ...state, password: action.payload };
case "dec_domain":
return { ...state, domain: action.payload };
case "dec_description":
return { ...state, description: action.payload };
case "reset_password":
return { ...state, password: "" };
case "reset":
return {};
default:
return state;
}
};
const decData = (dispatch) => async ({ id, secretKey }) => {
const response = await trackerApi.get("/api/password/" + id + "/");
var responseUser = response.data.username;
var responseDesc = response.data.description;
var decUsername = decryptRecord(responseUser, secretKey);
var decDescription = decryptRecord(responseDesc, secretKey);
dispatch({ type: "dec_username", payload: decUsername });
dispatch({ type: "dec_description", payload: decDescription });
};
const decPassword = (dispatch) => async ({ id, secretKey }) => {
const response = await trackerApi.get("/api/password/" + id + "/");
const responsePassword = response.data.password;
const decPassword = decryptRecord(responsePassword, secretKey);
dispatch({ type: "dec_password", payload: decPassword });
};
const resetPassword = (dispatch) => () => {
dispatch({ type: "reset_password" });
};
const reset = (dispatch) => () => {
dispatch({ type: "reset" });
};
export const { Provider, Context } = createDataContext(
passwdDetailReducer,
{ decData, decPassword, reset, resetPassword },
{ username: "", password: "", domain: "", description: "" }
);
解决方案
您想监听密码的更改,并且仅在密码不为空时复制。您可能还希望在单击按钮时禁用该按钮。
import React, { useContext, useEffect } from "react";
import { View, StyleSheet, Text, Clipboard } from "react-native";
import { Context as PasswdDetailContext } from "../context/PasswdDetailContext";
import { Button, Input } from "react-native-elements";
import { decryptRecord } from "../components/Crypto";
import { Context as AuthContext } from "../context/AuthContext";
import { NavigationEvents } from "react-navigation";
import Spacer from "../components/Spacer";
const PasswdDetailScreen = ({ navigation }) => {
const {
state: { username, password, domain, description },
decData,
decPassword,
resetPassword,
reset,
} = useContext(PasswdDetailContext);
const {
state: { secretKey },
} = useContext(AuthContext);
const id = navigation.getParam("id");
const clipboardPasswd = () => {
Clipboard.setString(password);
setTimeout(() => {
Clipboard.setString("");
resetPassword();
}, 10000);
};
useEffect(()=>{
if (password !== '') clipboardPasswd();
},[password]);
return (
<>
<NavigationEvents
onWillFocus={() => decData({ id, secretKey })}
onDidBlur={() => {}}
/>
<Text>Username: {username}</Text>
<Text>Password: {password}</Text>
<Text>Description: {description}</Text>
<Button
title="Copy Password"
onPress={() => decPassword({ id, secretKey })}
/>
<Input label="Password" />
</>
);
};
const styles = StyleSheet.create({});
export default PasswdDetailScreen;
推荐阅读
- powershell - powershell 在 foreach 循环之间插入文本
- mongoose - 猫鼬填充返回空
- python - 特殊序列有什么用,例如 python 中的 \number?
- ruby-on-rails - 如何在 Devise + Doorkeeper 中创建(注册/注册)用户
- mysql - 如何比较两个表中的数据并显示一个表中的数据
- c# - 在 C# 中将 MP3 转换为 MIDI
- html - 列表项的工具提示
- java - Java给一个类作为参数
- mysql - 使用 RAND() 从表中随机选择无法正常工作
- c++ - 通过代码构造 std::array 并初始化元素对象