我对我试图执行的代码感到困惑.我使用受控输入,并将来自API的响应传递给子组件,但它呈现最后一个值.

这是我的代码.

P传递我当前try 显示的数据行的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>
  );

当我单击行时,该州处于落后状态.不知道我错过了什么.

推荐答案

如果我正确地理解了问题是本地状态没有正确更新以匹配查询数据的row值,那么问题似乎是更新本地状态的useEffect挂钩具有不正确的依赖关系.

它应该使用data,而不是使用row,这样当查询到的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

  ...

在使用Reaction钩子时,强烈建议将eslint-plugin-react-hooks插件添加到您的eslint配置中,以便通过您的IDE轻松识别缺失和/或不正确的钩子依赖项.

Javascript相关问答推荐

同步功能在中间停止

类型错误:tasks.map不是函数(MERN堆栈)

如何避免使用ajax在Vue 3合成API中重定向

如何在加载的元数据上使用juserc和await中获得同步负载?

Angular:ng-contract未显示

fetch在本地设置相同来源的cookie,但部署时相同的代码不会设置cookie

如何访问Json返回的ASP.NET Core 6中的导航图像属性

zoom svg以适应圆

警告!合同执行期间遇到错误[执行已恢复](Base Layer 2)

Bootstrap动态选项卡在切换选项卡后保持活动状态,导致元素堆叠

我开始使用/url?q=使用Cheerio

Next.js(react)使用moment或不使用日期和时间格式

Angular 17—每当一个布尔变量变为真时触发循环轮询,只要它保持为真

无法使用单击按钮时的useState将数据从一个页面传递到另一个页面

我怎么在JS里连续加2个骰子的和呢?

图表4-堆叠线和条形图之间的填充区域

Next.js无法从外部本地主机获取图像

为什么我看到的是回复,而不是我的文档?

如何让SVG图标在被点击和访问后改变 colored颜色 ,并在被访问后取消点击时恢复到原来的 colored颜色 ?

ReferenceError:无法在初始化之前访问setData