提问人:cruz 提问时间:11/17/2023 最后编辑:Drew Reesecruz 更新时间:11/17/2023 访问量:51
React useState 不渲染当前的 onClick
React useState not rendering the current onClick
问:
我对我尝试执行的代码感到困惑。我正在使用受控输入,并将响应从 API 传递到子组件,但它正在呈现最后一个值。
这是我的代码。
传递我当前尝试显示的数据行的 ID:
<AdminInvociceDetail row={invoiceRowClicked} />
接收 ID 的组件
import React, { useState, useEffect } from "react";
import {
useFetchInvoiceQuery,
useUpdateInvoiceMutation,
} from "../../features/Invoices/InvoiceSlice";
import { useNavigate, Link } from "react-router-dom";
import "./Admin.css";
const AdminInvociceDetail = ({ row }) => {
const { data } = useFetchInvoiceQuery(row);
const [UpdateInvoice] = useUpdateInvoiceMutation();
//* state for the form
const [Id, setId] = useState("");
const [billtoname, setBillToName] = useState("");
const [clientname, setClientName] = useState("");
const [offc, setOffc] = useState("");
const [matterNo, setMatterNo] = useState("");
useEffect(() => {
setId(data?.ID);
setBillToName(data?.BillToName);
setOffc(data?.OFFC);
setClientName(data?.ClientName);
setMatterNo(data?.MatterNo);
}, [row]);
function ButtonLink({ to, children, className }) {
return (
<Link to={to}>
<button className={className}>{children}</button>
</Link>
);
}
return (
<div>
<div class="box">
<form class="ui form" onSubmit={handleSubmit}>
<h4 class="ui dividing header labels">Invoice Detail:</h4>
<div class="two fields">
<div class="field">
<label className="labels">Bill To Name</label>
<input
type="text"
name="BillToName"
placeholder="Bill To Name"
required
onChange={(e) => setBillToName(e.target.value)}
value={billtoname || ""}
/>
</div>
<div class="field">
<label className="labels">Client Location</label>
<select
class="ui fluid dropdown"
required
onChange={(e) => setClientName(e.target.value)}
value={clientname || ""}
>
<option value="">Location</option>
<option value="Becker - Tampa">Becker - Tampa</option>
<option value="Becker - Orlando">Becker - Orlando</option>
<option value="Becker - West Palm Beach">
Becker - West Palm Beach
</option>
<option value="Becker - Fort Myers">Becker - Fort Myers</option>
<option value="Becker - Coral Gables">
Becker - Coral Gables
</option>
<option value="Becker - Fort Lauderdale">
Becker - Fort Lauderdale
</option>
<option value="Becker - Morristown">Becker - Morristown</option>
<option value="Becker - Bradenton">Becker - Bradenton</option>
<option value="Becker - Stuart">Becker - Stuart</option>
<option value="Becker - Naples">Becker - Naples</option>
<option value="Becker - Sarasota">Becker - Sarasota</option>
<option value="Becker - Fort Walton Beach">
Becker - Fort Walton Beach
</option>
<option value="Becker - New York">Becker - New York</option>
<option value="Becker - Mount Laurel">
Becker - Mount Laurel
</option>
<option value="Becker - Red Bank">Becker - Red Bank</option>
<option value="Becker - Tallahassee">
Becker - Tallahassee
</option>
</select>
</div>
</div>
<div class="two fields">
<div class="field">
<label className="labels">Office</label>
<select
class="ui fluid dropdown"
required
onChange={(e) => setOffc(e.target.value)}
name="offc"
value={offc || ""}
>
<option value="">Office</option>
<option value="TAL">TAL</option>
<option value="ORL">ORL</option>
<option value="WPB">WPB</option>
<option value="FTM">FTM</option>
<option value="MIA">MIA</option>
<option value="FTL">FTL</option>
<option value="MOR">MOR</option>
<option value="STR">STR</option>
<option value="NAP">NAP</option>
<option value="BDT">BDT</option>
<option value="SAR">SAR</option>
<option value="FTW">FTW</option>
<option value="TAM">TAM</option>
<option value="MTL">MTL</option>
<option value="MOR">MOR</option>
<option value="RB">RB</option>
<option value="NY">NY</option>
<option value="DC">DC</option>
</select>
</div>
<div class="field">
<label className="labels">Matter No</label>
<input
type="text"
name="MatterNo"
placeholder="Matter No"
onChange={(e) => setMatterNo(e.target.value)}
value={matterNo || ""}
/>
</div>
</div>
<ButtonLink to="/" className="back-button">
Back to Invoice
</ButtonLink>
<button class="submit-button">Submit Invoice</button>
<div class="fields"></div>
</form>
</div>
</div>
);
当我单击行时,状态滞后。不知道我在这里错过了什么。
答:
1赞
Drew Reese
11/17/2023
#1
如果我理解正确,问题是本地状态没有正确更新以按值匹配查询的数据,那么问题似乎是更新本地状态的钩子具有不正确的依赖关系。row
useEffect
与其使用它,不如使用 ,这样当查询的结果更新时,效果可以运行并更新本地状态。如果已经有缓存的查询数据,还可以将初始状态值直接传递给挂钩。row
data
data
useState
例:
const AdminInvociceDetail = ({ row }) => {
const { data } = useFetchInvoiceQuery(row);
const [UpdateInvoice] = useUpdateInvoiceMutation();
// state for the form
const [Id, setId] = useState(data?.ID);
const [billtoname, setBillToName] = useState(data?.BillToName);
const [clientname, setClientName] = useState(data?.ClientName);
const [offc, setOffc] = useState(data?.OFFC);
const [matterNo, setMatterNo] = useState(data?.MatterNo);
useEffect(() => {
setId(data?.ID);
setBillToName(data?.BillToName);
setOffc(data?.OFFC);
setClientName(data?.ClientName);
setMatterNo(data?.MatterNo);
}, [data]); // <-- data is external dependency, not row
...
使用 React 钩子时,强烈建议将 eslint-plugin-react-hooks 插件添加到您的 eslint 配置中,以便通过 IDE 轻松识别缺失和/或不正确的钩子依赖项。
评论
1赞
Drew Reese
11/17/2023
@RossAllen 精彩的补充,谢谢。
0赞
cruz
11/17/2023
哇。我想踢我自己。谢谢德鲁。这成功了
0赞
cruz
11/17/2023
并感谢您的推荐!!!
评论