I've been stuck on this problem for quite some time. I am using a couple of different states to render values inside a card after they have been input into the form. The first state takes in the values and changes the initial state. the second state takes in the values after a mathematical function has been performed and renders them onto the card. My desired outcome is a fully reset state that allows for new values to be entered, and then subsequently having a new card rendered beneath the initial card all whilst maintaining the previous values that have already been input.
import Navbar from '../../components/NavBar'
import { FormControl, InputLabel, Input, Button, FormHelperText } from '@mui/material'
import ExpenseCard from '../../components/ExpenseCard'
import axios from 'axios'
import { React, useState } from 'react'
import ReactDOM from 'react-dom'
import { Grid } from '@mui/material'
import { categoryResult, calcSumTotal } from '../../utils/CategoryResult'
const Budget = () => {
const [ categoriesToAdd, setCategoriesToAdd] = useState(0);
const [ committedCategoriesToAdd, setCommittedCategoriesToAdd] = useState(0);
const [ renderCardsAdded, setRenderCardsAdded] = useState({
category: '',
actualValue: 0,
goalValue: 0,
result: 0
});
// by building out the states in the budget page we have negated the need to use an expenseContext and import it, removing confusion. doing this also allows us to compile the functions that we need to use to handle changes in the form.
const handleAddExpense = (category, actualValue, goalValue) => {
let result = categoryResult(actualValue, goalValue);
setRenderCardsAdded({...renderCardsAdded, category: category, actualValue, goalValue, result });
}
const renderTheCard = () => {
document.getElementById('renderhere').innerText =
<ExpenseCard category={renderCardsAdded.category} actualValue={renderCardsAdded.actualValue} goalValue={renderCardsAdded.goalValue} result={renderCardsAdded.result} />
}
const handleInputChange = ({ target: { name, value } }) => setExpenseState({ ...expenseState, [name]: value })
const [ expenseState, setExpenseState ] = useState({
category: ' ',
goalValue: 0,
actualValue: 0,
})
/// this is basically the expenseform from the components folder but i circumvented the necessity to import it by building it out on the budget page.
const CategoryForm = () => [
<FormControl>
<Grid container rowSpacing={1} columnSpacing={{ xs: 1 }}>
<Grid item xs={2}>
<Input name="category" aria-describedby="expense category" value={expenseState.category} onChange={handleInputChange}/>
<FormHelperText id="my-helper-text-1">expense category</FormHelperText>
</Grid>
<Grid item xs={2}>
<Input type="number" name="actualValue" aria-describedby="actual value" value={expenseState.actualValue} onChange={handleInputChange}/>
<FormHelperText id="my-helper-text-2">actual expense</FormHelperText>
</Grid>
<Grid item xs={2}>
<Input type="number" name="goalValue" aria-describedby="goal value" value={expenseState.goalValue} onChange={handleInputChange}/>
<FormHelperText id="my-helper-text-3">goal expense</FormHelperText>
</Grid>
<Grid item xs={2}>
<Button onClick={
() => {
handleAddExpense(expenseState.category, expenseState.actualValue, expenseState.goalValue)
renderTheCard()}}>Add</Button>
</Grid>
</Grid>
</FormControl>
]
return (
<>
<Navbar />
<hr />
<CategoryForm />
<div id="renderedCategories">
{[...Array(committedCategoriesToAdd)].map((value: undefined, index: number) => (
<CategoryForm id={index + 1} key={index} />))}
</div> */}
<h1>This is the Budget Page</h1>
<div id="renderhere"></div>
</>
)
}
export default Budget
this code currently renders Object Object to the page with no information displayed outside of that. Further, another issue I've encountered is the input form is only allowing me to input 1 character at a time and to further input characters i have to refocus the input. Not sure what is causing this... using MUI styling, and react.