Home > Software engineering >  Is there a way i can wait for a state to be set before rendering?
Is there a way i can wait for a state to be set before rendering?

Time:03-17

I'm building an ETH wallet for iOS. This is just a prototype of a screen, but I'm facing an error. Everything works just fine, except the part where i have to map through the transactions. Well, the thing is it renders the app before it fetches the transactions, so it would always show an error when mapping and that it's not a function.

However, if i preload the transactions, change code and reload, it would map ( only for one time ), reload again and the errors are back.

Is there anything i can do about this?

const Wallet = ({ navigation }) => {
    const Tab = createMaterialTopTabNavigator();
    const [ wallet, setWallet ] = useState("⌛");
    const [ address, setAddress ] = useState("⌛");
    const [ balance, setBalance ] = useState("⌛");
    const [ mnemonic, setMnemonic ] = useState("⌛");
    const [ transactions, setTransactions ] = useState();
    console.log(transactions)
    useEffect(async () => {
        const retrieve_connect = async () => {
            const result = await SecureStore.getItemAsync("pKey");
            if (result) {
                const decoded = await JWT.decode(result, "1239SEH9S8FH9S8EFSUEFBSIUFENEIU");
                if (!decoded ) {
                    navigation.push('SignUp')
                }
                console.log(decoded);
                setAddress(decoded.address);
                setWallet(decoded.privateKey);
                setMnemonic(decoded.mnemonicPhrase);
            } else {
                navigation.push('SignUp')
            }
            const connection = new ethers.getDefaultProvider('kovan');
            // ethers.providers.JsonRpcProvider('https://eth-mainnet.alchemyapi.io/v2/aw_ATN5yoZ578XsQUVEhaevmchG9e_iT');
            const decode = await JWT.decode(result,"1239SEH9S8FH9S8EFSUEFBSIUFENEIU")
            if (!decode) {
                navigation.push('SignUp');
            }
            const wallet = new ethers.Wallet(decode.privateKey);   
            const signer = wallet.connect(connection);
            const addy = await signer.getAddress();
            const balance = await signer.getBalance();
            const response = await fetch(`https://api-kovan.etherscan.io/api?module=account&action=txlist&address=${addy}&startblock=0&endblock=99999999&page=1&offset=10&sort=asc&apikey=2KQ9YKPQ1VG4E5FE4PUG7E5CHJWIVK2D43`)
            const res = await response.json();
            const transactions = await res.result;
            setTransactions(res.result)
            console.log(transactions);
            setBalance(ethers.utils.formatEther(balance._hex));
            setAddress(addy);
        }
        const save = async () => {
            await SecureStore.setItemAsync("key", "test 123")
        }
        save();
        console.log(address);
        retrieve_connect();
    }, [])
    const copyToClipboard = () => {
        Clipboard.setString(address);
        Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success);
      };
      // only for beta testing.
      const copyPrivateKey = () => {
        Clipboard.setString(wallet);
      };
      // Share Button
      const onShare = async () => {
        Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success);
        try {
          const result = await Share.share({message:address});
          if (result.action === Share.sharedAction) {
            if (result.activityType) {
              // shared with activity type of result.activityType
            } else {
              // shared
            }
          } else if (result.action === Share.dismissedAction) {
            // dismissed
          }
        } catch (error) {
          alert(error.message);
        }
      };
    return (
        <View style={styles.container}>
            {/* <Text>Below is your Address.</Text> */}
            <View style={styles.secondContainer}>
                <Button style={styles.ButtonText} onPress={copyToClipboard} title={`${address.substring(0, 15)}..`} />
                </View> 
            {/* <Text>Below is your PrivateKey</Text>
            <TouchableOpacity onPress={copyPrivateKey}>
            <Text>{JSON.stringify(wallet)}</Text>
            </TouchableOpacity>
            <TouchableOpacity>
            <Text>{JSON.stringify(mnemonic)}</Text>
            </TouchableOpacity> */}
            <View style={styles.thirdContainer}>
            <Text>Balance:</Text>
            <TouchableOpacity>
            <Text>{balance} ETH </Text>
            </TouchableOpacity>
            <Link to="/LogOut">Delete Token</Link>
            <Link to="/Send">Send</Link>
            {/* { transactions.map(transaction => <Text key={transaction}>{transaction.hash}</Text>)} */}
            </View>
            <View style={styles.fourthContainer}>
            <TouchableOpacity  onPress={onShare}>
                <LinearGradient colors={['#ee0979','#ff6a00']} start={[0.0, 0.0]} end={[1.0, 1.0]} style={styles.button}>
                <Text style={styles.TextCopy}>Share Address </Text>
                </LinearGradient>
                </TouchableOpacity>
                </View>
        </View>
    )
}


export default Wallet

CodePudding user response:

You can return empty component if your states are empty:

if(!wallet || !balance || ...) return <></>
return  <View style={styles.container}>
...

CodePudding user response:

What you need is a conditional render. Render component if wallet exists else render empty fragment.
return(wallet ? *component* : <></>)

  • Related