У меня есть фрагмент JS-кода, который должен извлекать данные из конечной точки и заполнять форму из данных.
Основная проблема, с которой я столкнулся, заключается в том, что он заполняет только первое поле. Остальное не заполняет.
Компонент реакции показан ниже.
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.info("Edit Package ID -> ", editPackageId);
const navigate = useNavigate();
useEffect(async () => {
const data = await retrievePackage();
console.info(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 установит состояние/значения для объекта.
Я могу подтвердить, что данные API получены, и, чтобы еще больше меня запутать, текстовое поле заполняется packageInfo.packageName. Но в остальном ни одного. Я уверен, что имена также совпадают с извлечением данных.
Для лучшего понимания ниже мой ответ от конечной точки.
{
"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"
}
Любая помощь очень ценится. Я несколько дней бился головой о кирпичную стену с этой проблемой. Заранее спасибо.
Вы имеете в виду, что форма отображает ввод только с полем имени пакета, но не с другими?
Да правильно @sid
Ваш метод onChange неверен, поэтому вы получаете объект в ответе от axios, но как только один из onChange(s) запускается, состояние изменяется, и у вас остается только первое поле в дереве, а другие значения становятся нулевыми /неопределенный.
Попробуйте изменить метод onChange на - e=> setPackageInfo({...packageInfo, packageName: e.target.value})
для packageName, e=> setPackageInfo({...packageInfo, height: e.target.value})
для высоты и так далее.
Спасибо. Я получаю «Uncaught TypeError: Невозможно прочитать свойства неопределенного (чтение« значения »)» при обновлении до onChange = {e => setPackageInfo({...packageInfo, packageName: e.target.value})}. Есть идеи? Это происходит, когда я печатаю в текстовом поле. Исходная проблема с заполнением поля packageName только после использования предложенного вами useEffect. Ценю твою помощь.
Кажется, что форма имеет какое-то внутреннее состояние. В Shopify есть пакет для управления состоянием формы: @shopify/react-form-state.
В этом примере, если вы хотите, чтобы все было просто, создайте обработчик состояния для каждого поля. Это не медленно, так как реакция группирует вызовы 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,
}
...
Спасибо. Я получаю «Uncaught TypeError: Невозможно прочитать свойства неопределенного (чтение« значения »)» при обновлении до onChange = {e => setPackageInfo({...packageInfo, packageName: e.target.value})}. Есть идеи? Также попробовал onChange = {e => setPackageInfo({...packageInfo, [packageName]: e.target.value})}. Это происходит, когда я печатаю в текстовом поле. Исходная проблема с заполнением поля packageName только после использования предложенного вами useEffect. Ценю твою помощь.
При проверке @shopify/полярные документы компонент TextField принимает функцию со значением параметра, а не событие. Я отредактирую свой ответ, чтобы отразить это. Кроме того, скобки в fieldName должны были показывать значение универсальной переменной, то есть имя текущего поля.
Спасибо, Крисс. Это устранило ошибку, о которой я упоминал. Однако исходная проблема с отображением packageName только в текстовом поле, а не в других, все еще существует. Любая идея, почему это происходит?
Спасибо разобрался с этим. Судя по всему, модуль не принимает целочисленные значения. Преобразовал его в строку, и это сработало. Еще раз спасибо за помощь.
Не могли бы вы смоделировать проблему в JSFiddle или в песочнице кода, чтобы мы могли решить ее непосредственно там.