I have 4 input fields as below. name,count,amount,price. And two text fields, commission and total.
If user enter values at price and count then amount(price * count) should be calculated. If user enters values at price and amount then count (amount / price) should be calculated. In both cases, commission=0.02*amount and total=amount+commission should be updated.
So, I tried below code snippet as a start for updating amount and commission based on price. But it is not updating.
//App.js
import React from "react";
import App1 from "./src/screens/createCoin.jsx";
import * as Font from "expo-font";
export default function App() {
return <App1 />;
}
//createCoins.jsx
import React, { Component, useState } from "react";
import {
Container,
Header,
Content,
H1,
Text,
Form,
Item,
Input,
} from "native-base";
export default function createCoins() {
const [name, setName] = useState("");
const [price, setPrice] = useState("");
const [amount, setAmount] = useState("");
const [commission, setCommission] = useState("");
const [count, setCount] = useState("");
updateDetails = (text, type) => {
console.log("came to update Details...");
if (type === "price") {
const price = parseFloat(text);
setPrice(price);
setAmount(price * count);
setCommission(amount * 0.002);
}
};
return (
<Container>
<Header />
<Content>
<Form>
<Item>
<Input
placeholder="coin name"
onChangeText={(text) => setName(text)}
/>
</Item>
<Item>
<Input
placeholder="number of coins"
onChangeText={(text) => setCount(count)}
/>
</Item>
<Item>
<Input
placeholder="Amount Invested"
onChangeText={(text) => setAmount(amount)}
/>
</Item>
<Item last>
<Input
placeholder="coin price"
onChangeText={(text) => updateDetails(text, "price")}
/>
</Item>
</Form>
<Text>Commission: {commission}</Text>
<Text>Total Amount: {commission + amount}</Text>
</Content>
</Container>
);
}
Can you please suggest.
After changing the code of createCoin.jsx as below. The text field "total amount" is getting updated but how to update the input field amount? I tried adding attribute value={state.amount} to it but didn't work as getting error as invalid prop.
import React, { Component, useState } from "react";
import {
Container,
Header,
Content,
H1,
Text,
Form,
Item,
Input,
} from "native-base";
export default function createCoins() {
const [name, setName] = useState("");
//const [price, setPrice] = useState("");
//const [amount, setAmount] = useState("");
//const [commission, setCommission] = useState("");
//const [count, setCount] = useState("");
const [state, setState] = useState({
price: 0,
amount: 0,
commission: 0,
count: 0,
});
/*const updatePrice = (value) => {
console.log("came to update Details...");
if (count) {
setPrice(value);
setAmount(value * count);
}
};*/
updateDetails = (text, type) => {
console.log("came to update Details...");
if (type == "count") {
setState({
...state,
count: text,
});
}
if (type === "price") {
console.log("came inside price");
const price = parseFloat(text);
setState({
...state,
price: price,
amount: price * state.count,
commission: state.price * state.count * 0.002,
});
//setPrice(price);
//setAmount(price * count);
//setCommission(amount * 0.002);
console.log("price:" + price);
console.log(state.amount);
console.log(state.commission);
}
};
return (
<Container>
<Header />
<Content>
<Form>
<Item>
<Input
placeholder="coin name"
onChangeText={(text) => setName(text)}
/>
</Item>
<Item>
<Input
placeholder="number of coins"
onChangeText={(text) => updateDetails(text, "count")}
/>
</Item>
<Item>
<Input
placeholder="Amount Invested"
value={state.amount}
onChangeText={(text) => updateDetails(text, "amount")}
/>
</Item>
<Item last>
<Input
placeholder="coin price"
onChangeText={(text) => updateDetails(text, "price")}
/>
</Item>
</Form>
<Text>Commission: {state.commission}</Text>
<Text>Total Amount: {state.commission + state.amount}</Text>
</Content>
</Container>
);
}
Here's what I did
import React, { Component, useState, useEffect, useRef } from "react";
import {
Container,
Header,
Content,
H1,
Text,
Form,
Item,
Input,
} from "native-base";
export default function createCoins() {
const [name, setName] = useState("");
const [amount, setAmount] = useState("");
const [count, setCount] = useState("");
const [price, setPrice] = useState("");
const [commission, setCommission] = useState("");
// used to regulate when calculations are made
const [ focusedInput, setFocus ] = useState(null)
// run an effect when price, count, or amount changes
useEffect(()=>{
// if price and count exist and user isnt changing amount, calculate amount
if(price && count && focusedInput !== 'amount'){
setAmount( price * count );
}
// if price and count exist and user isnt changing count, calculate count
else if(price && amount && focusedInput !== 'count'){
setCount( amount / price )
}
},[price,count,amount])
// when amount changes, update commission and total
useEffect(()=>{
if(isNaN(amount))
setCommission('')
if(amount)
setCommission( amount * 0.002);
},[amount])
return (
<Container>
<Header />
<Content>
<Form>
<Item>
<Input
placeholder="coin name"
onChangeText={setName}
keyboardType="decimal-pad"
/>
</Item>
<Item>
<Input
placeholder="number of coins"
onChangeText={text => setCount(parseFloat(text))}
keyboardType="decimal-pad"
value={count.toString()}
onFocus={()=>setFocus("count")}
/>
</Item>
<Item>
<Input
placeholder="Amount Invested"
onChangeText={text => setAmount(parseFloat(text))}
keyboardType="decimal-pad"
value={amount.toString()}
onFocus={()=>setFocus("amount")}
/>
</Item>
<Item last>
<Input
placeholder="coin price"
onChangeText={text=>setPrice(parseFloat(text))}
keyboardType="decimal-pad"
value={price.toString()}
onFocus={()=>setFocus("price")}
/>
</Item>
</Form>
<Text>Commission: {commission}</Text>
<Text>Total Amount: {commission +amount}</Text>
</Content>
</Container>
);
}
focusedInput
exists to prevent the auto calculation of a value when its in focused (being changed). Without the focusedInput
conditional, if price
and count
or amount
existed, then the third value would be derived from the two values, even when you tried to change the third.
For an example, if you tried to edit the count
textInput field while price
and amount
exists, the count
textfield would overriden by setCount(amount/price)
before you could type your next character.
By verifying that the field is not in focus before auto calculating its value, this undesired effect is avoided