I have code as below. My app fetches encrypted password from API and after decrypting, copies it to clipboard for few seconds. Decrypting takes place the moment I press Copy Password
button. However, when I press button 1 time my password isn't copied to clipboard which means, that for some reason state password
wasn't changed. Password is copied to clipboard only after I press it 2 times in short amount of time. What could be reason behind that? I've tested case "dec_password"
and decPassword
quite a bit and to me it seems, actual issue happens in component, not in context.
Component:
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;
Context:
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: "" }
);