1
I’m doing a compound interest calculation.
I receive the form data valores.js
, called by function enviarValores()
with the onSubmit={handleSubmit(enviarValores)}
and I want to send the answers results
(an array) for the Resultados.js
however, for each input, in console.log, it already shows the results. But it does not show on the screen. Only when I input new data.
Doubt, how to make it call Results.js only when I click the submit button?
And what’s wrong with showing the data on the screen?
Archives
Values.js
import useForm from "../../controllers/useForm";
import { Container } from "./styles";
import Resultados from "../resultados/Resultados";
export default () => {
const [{ values, loading }, handleChange, handleSubmit] = useForm();
const [results, setResults] = useState([]);
const enviarValores = () => {
const capitalInicial = parseFloat(values.montanteInicial) || null;
const rate = parseFloat(values.taxaJurosMensal) || null;
const period = parseInt(values.periodoMeses) || null;
let totalAmount = 0;
// let valorMensalPorcentagem = 0;
let valorMensal = 0;
let taxaJurosPorcentagem = rate / 100;
for (let i = 1 ; i <= period ; i++) {
totalAmount = capitalInicial * ((1 + taxaJurosPorcentagem)**i);
valorMensal = totalAmount - capitalInicial;
results.push({ month: i, totalAmount: totalAmount.toFixed(2), valorMensal: valorMensal.toFixed(2)});
};
};
useEffect(() => {
return () => {
setResults(results);
}
},);
return (
<div className="row">
<Container>
<div className="row titulo">
<h1>Juros Composto</h1>
</div>
<form className="col s12" onSubmit={handleSubmit(enviarValores)}>
<div className="row">
<div className="input-field col s6">
<input
onChange={handleChange}
name="montanteInicial"
id="montanteInicial"
type="number"
className="validate"
required
step="0.01"
min="1000"
max="99999"
/>
<label htmlFor="montanteInicial">Montante Inicial</label>
</div>
</div>
<div className="row">
<div className="input-field col s6">
<input
onChange={handleChange}
name= "taxaJurosMensal"
id="taxaJurosMensal"
type="number"
className="validate"
required
step="0.01"
min="-99999.99"
max="999999.99"
/>
<label htmlFor="taxaJurosMensal">Taxa de Juros Mensal</label>
</div>
</div>
<div className="row">
<div className="input-field col s6">
<input
onChange={handleChange}
type="number"
id="periodoMeses"
name="periodoMeses"
className="validate"
required
pattern="[0-9]+$"
min="1"
max="90"
/>
<label
htmlFor="periodoMeses"
data-error="Preencha o campo com a quantidade de meses"
className="active">Período (meses)
</label>
</div>
</div>
<button className="btn waves-effect waves-light" type="submit" name="action">{loading ? "Enviando..." : "Enviar"}</button>
</form>
</Container>
<Resultados results={results} />
</div>
);
}
Results.js
function Resultados({results}) {
console.log(results);
return(
<div>
<ul>
{ results.map((row, i) =>
<li key={i}>
<strong scope='row'>{row.month}</strong>
<p>R${row.totalAmount}</p>
</li>
)}
</ul>
</div>
)
}
export default Resultados;
The code is available at https://stackblitz.com/edit/juros-compostos
code after the change
const enviarValores = () => {
const capitalInicial = parseFloat(values.montanteInicial) || null;
const rate = parseFloat(values.taxaJurosMensal) || null;
const period = parseInt(values.periodoMeses) || null;
const resultsAux = [];
let totalAmount = 0;
// let valorMensalPorcentagem = 0;
let valorMensal = 0;
let taxaJurosPorcentagem = rate / 100;
for (let i = 1 ; i <= period ; i++) {
totalAmount = capitalInicial * ((1 + taxaJurosPorcentagem)**i);
valorMensal = totalAmount - capitalInicial;
resultsAux.push({ month: i, totalAmount: totalAmount.toFixed(2), valorMensal: valorMensal.toFixed(2)});
};
setResults(resultsAux);
};
useEffect(() => {
return () => {
setResults([]);
}
},[]);
function Resultados({results}) {
return(
<Container>
<ul>
{ results.map((row, i) =>
<li key={i}>
<strong scope='row'>{row.month}</strong>
<p>R${row.totalAmount}</p>
</li>
)}
</ul>
</Container>
)
}
I did it this way, but he just entered the last record of the loop. How to use inside the for???
for (let i = 1 ; i <= period ; i++) {

 totalAmount = capitalInicial * ((1 + taxaJurosPorcentagem)**i);

 valorMensal = totalAmount - capitalInicial;

 setResults([
 ...results, 
 { month: i, 
 totalAmount: totalAmount.toFixed(2), 
 valorMensal: valorMensal.toFixed(2)
 }
 ])
– Rebeca Nonato
I got it, I’ll put the code with the result.
– Rebeca Nonato
Great that you got!! You have to be very careful when using Set of some state within the for, because the set function of States does not return value at runtime, they are asynchronous
– Gustavo Bordin