React状态更新后UI未重新渲染问题求助
React状态更新后UI未重新渲染问题求助
我正在用React JS开发一个费用追踪应用,遇到了个头疼的问题——明明更新了状态变量,但UI却没跟着变化。对于每一笔新增的费用,我想要实现的逻辑是:
- 如果费用名称已经存在,不会新增一行记录,而是把新费用的金额加到已有金额上;
- 如果费用名称不存在,就新增一行费用记录。
通过控制台日志我能看到,在第一种情况(名称已存在)下,groupedExpenses变量确实更新了,但费用行的UI却完全没反应。
下面是我的代码:
1. App.jsx
import Expenses from "./components/Expenses"; import Form from "./components/Form"; import { useState } from "react"; function App() { const [groupedExpenses, setGroupedExpenses] = useState({}); function addExpense(name, amount) { setGroupedExpenses((previousGroupedExpenses) => { let newGroupedExpenses = { ...previousGroupedExpenses }; console.log(newGroupedExpenses); if (name in newGroupedExpenses) { newGroupedExpenses[name] += parseFloat(amount.replace(",", ".")); } else { newGroupedExpenses[name] = parseFloat(amount.replace(",", ".")); } return newGroupedExpenses; }); } return ( <div className="expensesapp stack-large"> <h1>Expense Manager</h1> <Form addExpense={addExpense} /> <Expenses groupedExpenses={groupedExpenses} /> </div> ); } export default App;
2. Form.jsx
import { useState } from "react"; import TextField from "@mui/material/TextField"; import Stack from "@mui/material/Stack"; import Autocomplete from "@mui/material/Autocomplete"; import InputAdornment from "@mui/material/InputAdornment"; import Icon from "@mui/material/Icon"; function Form(props) { const [expenseName, setExpenseName] = useState(""); const [expenseAmount, setExpenseAmount] = useState(""); const [options, setOptions] = useState([]); function handleChangeName(event) { setExpenseName(event.target.value); } function handleSelectSuggestion(event, value) { setExpenseName(value); } function handleChangeAmount(event) { setExpenseAmount(event.target.value); } function handleSubmit(event) { event.preventDefault(); props.addExpense(expenseName, expenseAmount); if (!options.includes(expenseName)) { setOptions([...options, expenseName]); } setExpenseName(""); setExpenseAmount(""); } return ( <form onSubmit={handleSubmit}> <div className="expense"> <Stack direction="row" spacing={1} sx={{ width: 300 }}> <Autocomplete sx={{ m: 1, width: "25ch" }} id="free-solo" freeSolo onInputChange={handleChangeName} onChange={handleSelectSuggestion} options={options} renderInput={(params) => ( <TextField {...params} label="nome" value={expenseName} /> )} /> <TextField label="valor" id="outlined-start-adornment" sx={{ m: 1, width: "25ch" }} onChange={handleChangeAmount} value={expenseAmount} slotProps={{ input: { startAdornment: ( <InputAdornment position="start">R$</InputAdornment> ), }, }} /> <button type="submit" className="btn btn__primary btn__lg"> <Icon>add_circle</Icon> </button> </Stack> </div> </form> ); } export default Form;
3. Expenses.jsx
function Expenses(props) { console.log(props.groupedExpenses); return ( <ul role="list" className="expenses-list stack-large stack-exception" aria-labelledby="list-heading" > {props.groupedExpenses !== undefined && Object.entries(props.groupedExpenses).map(([k, v]) => ( <div> <li className="expense stack-small"> <input type="text" className="input input-name input__lg" name="name" autoComplete="off" defaultValue={k} readOnly /> <input type="text" className="input input-value input__lg" name="value" autoComplete="off" defaultValue={v} readOnly /> </li> </div> ))} </ul> ); } export default Expenses;
有没有大佬能帮我指出哪里出错了?万分感谢!
备注:内容来源于stack exchange,提问作者vacosti
相关产品推荐
相关产品推荐

