反应不从获取数据设置状态

React not setting state from fetch data

我有一段 React JS 代码应该从端点获取数据并从数据填充表单。

我遇到的主要问题是它只填充了第一个字段。 它不会填充其余部分。

react组件如下

import React, { useState, useCallback, useEffect } from "react";
import {  Page, Button, Stack, Card, Form, FormLayout, TextField, TextContainer, Modal, Toast, TextStyle, Loading } from "@shopify/polaris";
import axiosInstance from "../common/RequestHandler";
import { useParams } from 'react-router-dom';
import { useNavigate } from "react-router";

function EditPackages(){
    const [errorToastActive, setErrorToastActive] = useState(false);

    const [active, setActive] = useState(false);
    const [isLoading, setIsLoading] = useState(false);

    const [height, setHeight] = useState('');
    const [width, setWidth] = useState('');
    const [depth, setDepth] = useState('');
    const [maxWeight, setMaxWeight] = useState('');
    const [packageName, setPackageName] = useState('');
    const [packageId, setPackageId] = useState(null);
    const [btnLoadingState, setBtnLoadingState] = useState(false);

    const [btnLoadingState, setBtnLoadingState] = useState(false);

    const toggleErrorToastActive = useCallback(() => setErrorToastActive((errorToastActive) => !errorToastActive), []);

    const errorToastMarkUp = errorToastActive ? (
        <Toast content="Error in editing your package" error onDismiss={toggleErrorToastActive} />
    ) : null;


    const params = useParams();
    const editPackageId = params.editPackageId;

    console.log("Edit Package ID -> ", editPackageId);

    const navigate = useNavigate();

    useEffect(async () => {
        const data = await retrievePackage();
        console.log(data);
        setMaxWeight(data.maxWeight);
        setDepth(data.depth);
        setHeight(data.height);
        setWidth(data.width);
        setPackageName(data.packageName);
    }, [editPackageId]);

    const backToPackages = function (){
        navigate('/app/packages');
    }

    const getPackage = useCallback(async () => {
        setPackageInfo(await retrievePackage());
    }, []);

    async function retrievePackage(){
        setIsLoading(true);
        const resp1 = await axiosInstance.get('/packageInfo?packageId=' + editPackageId);
        setIsLoading(false);
        return await resp1.data;
    }
    
    return (
        <Page title="Edit Package" fullWidth>
            {errorToastMarkUp}
            <Form>
                <FormLayout>
                    <TextField label="Package Name" value={packageName} onChange={setPackageName} autoComplete="off" />
                <TextField label="Height in CM" value={height} onChange={setHeight} autoComplete="off" />
                <TextField label="Width in CM"  value={width} onChange={setWidth} autoComplete="off" />
                <TextField label="Depth in CM"  value={depth} onChange={setDepth} autoComplete="off" />
                <TextField label="Max Weight in Grams"  value={maxWeight} onChange={setMaxWeight} autoComplete="off" />
                    <Button submit>Submit</Button>
                </FormLayout>
            </Form>
        </Page>
    );
}

export default EditPackages;

getPackage 方法用于从端点检索数据,我希望 setPackageInfo 为对象设置 state/values。

我可以确认检索到了 API 数据,更让我困惑的是,它用 packageInfo.packageName 填充了文本框。但其余的,none。 我确定名称也与检索到的数据匹配。

为了更好的理解,下面是端点的回复。

{
    "id": 25,
    "mId": 1,
    "height": 123,
    "width": 35,
    "depth": 3,
    "maxWeight": 4566,
    "created_at": "2022-02-18T21:13:47.000000Z",
    "updated_at": "2022-02-18T21:13:47.000000Z",
    "packageName": "Some random name"
}

非常感谢任何帮助。几天来,我一直在为这个问题苦苦思索。提前谢谢你。

你的 onChange 方法不正确,这就是为什么你在 axios 的响应中得到一个对象,但是一旦其中一个 onChange(s) 运行,状态就会改变,你只剩下树中的第一个字段并且其他值变为 null/undefined。 尝试将 onChange 方法更改为 -
e=> setPackageInfo({...packageInfo, packageName: e.target.value}) for packageName,
e=> setPackageInfo({...packageInfo, height: e.target.value}) for height,依此类推。

表单似乎有一些内部状态。 Shopify 有一个用于管理表单状态的包:@shopify/react-form-state.

对于此示例,如果您想保持简单,请为每个字段创建一个状态挂钩。这并不慢,因为 react 组在重新呈现中调用 setState 并且如果发出多个请求,页面将不会刷新,具体取决于字段数,但只会刷新一次。

const [packageName, setPackageName] = useState("");
const [height, setHeight] = useState("");

async function retrievePackage(){
  setIsLoading(true);
  const response = await axiosInstance.get('/packageInfo?packageId=' + editPackageId);
  setIsLoading(false);
  return response.data;
}

useEffect(() => {
  const data = await retrievePackage();
   
  setPackageName(data.packageName);
  setHeight(data.height);
  ...
}, []);

<TextField
  value={packageName}
  onChange={setPackageName}
/>
<TextField
  value={height}
  onChange={setHeight}
/>

然后提交所有钩子组成的对象

const formData = {
  packageName,
  height,
}
...