У меня есть динамические поля ввода, которые поступают из моей базы данных. создание полей ввода не является проблемой. однако, как только пользователь вводит информацию, он может захотеть вернуться и изменить ввод. У меня проблемы с компонентом редактирования. Кажется, что если я что-нибудь поставлю в свойство value, текст в поле не изменится. Для ясности предположим, что у меня есть 5 входных данных, но пользователь заполняет только 2. Я хочу, чтобы их данные отображались на правильных входных данных. Вот что я делаю.
useEffect(() => {
fetchPlatformInputs();
}, []);
const fetchPlatformInputs = async () => {
const fetchInputs = async () => {
const fetchedInputs = await API.graphql({
query: sortInputsByType,
variables: { type: "*", sortDirection: "ASC" },
});
const { items } = fetchedInputs.data.sortInputsByType; <--- the input fields
// Then the user's input for each field is held in context (which is derived from the user table) so I loop over both object arrays to create one object array of dynamic inputs with user data.
contextUser.inputData.map((contextData) => {
for(const item of items) {
if (contextData.inputType === item.inputType) {
item.inputData = contextData.inputData;
}
}
});
// Now I have an object array that joined the dynamic inputs and user data and I set put that into state.
setPlatformInputs(items);
};
/// that is just a useState combo. I loop over this variable to create the dynamic inputs.
const [platformInputs, setPlatformInputs] = useState([]);
//. Okay now for the part I can't figure out.
// here is where I hold the form data:
const [formValues, setFormValues] = useState([]);
// the onchange handler builds an object array for database insertion.
let handleChangeEvent = (e, inputType, inputData, isFabIcon, iconColor, imagePath) => {
setFormValues({
...formValues,
[inputType]: {
inputType: inputType,
inputData: inputData,
isFabIcon: isFabIcon,
iconColor: iconColor,
imagePath: imagePath,
},
});
console.info("form values are ", formValues);
};
//. here are the dynamic fields
{platformInputs?.length > 0 &&
platformInputs.map((input, index) => (
<MDBRow
className = "mx-auto my-2 text-center"
key = {"r" + index + "_" + input.inputType}
>
<MDBCol sm = "2" key = {"c1_" + input.inputType}>
// image or icon goes here
</MDBCol>
<MDBCol sm = "10" key = {"c2_" + input.inputType}>
<MDBInput
name = {["input_" + input.inputType]}
label = {[capitalizeWords(input.inputType)]}
type = "text"
value = {input.inputData}. <-- here is the problem. I can't figure out how to display the initial incoming user data and update it with the state formValues variable derived from the onChange handler
onChange = {(e) =>
handleChangeEvent(
e,
input.inputType,
input.inputData,
input.isFabIcon,
input.iconColor,
input.imagePath
)
}
/>
</MDBCol>
</MDBRow>
))}
Так что это собирает данные и отображает их отлично. Единственная проблема заключается в том, что состояние не работает, поэтому пользователь не может редактировать поле. Входное значение остается неизменным независимо от того, что вводит пользователь.
Обратите внимание, что пользователю не нужно вводить данные в каждое поле ввода. поэтому переменная formValues содержит только те, которые они используют. В противном случае я бы, вероятно, просто перебрал массив formValues. ' Спасибо за помощь.
Базовый пример
import React, { useState, useEffect } from 'react';
const DynamicInputFields = () => {
const [userData, setUserData] = useState([]);
const [inputFields, setInputFields] = useState([]);
useEffect(() => {
// fetch user data from database
const fetchUserData = async () => {
const response = await fetch('your-api-endpoint');
const data = await response.json();
setUserData(data);
};
fetchUserData();
}, []);
useEffect(() => {
setInputFields(userData.map((item, index) => (
<div key = {index}>
<input
type = "text"
value = {item.value}
onChange = {(e) => handleInputChange(e, index)}
/>
</div>
)));
}, [userData]);
const handleInputChange = (e, index) => {
const updatedData = [...userData];
updatedData[index].value = e.target.value;
setUserData(updatedData);
};
return (
<form>
{inputFields}
<button type = "submit">Submit</button>
</form>
);
};
export default DynamicInputFields;
Я получил это из чата gpt, и это то, что я искал...
import React, { useState } from 'react';
const DynamicForm = ({ formData, userData }) => {
const [formValues, setFormValues] = useState({});
const handleInputChange = (event) => {
setFormValues({
...formValues,
[event.target.name]: event.target.value
});
};
return (
<form>
{formData.map((input, index) => {
// this is the part I couldn't figure out how to do
const inputValue = userData.find((data) => data.name === input.name);
// end part I couldn't figure out
return (
<div key = {index}>
<label htmlFor = {input.name}>{input.label}</label>
<input
type = {input.type}
id = {input.name}
name = {input.name}
value = {inputValue ? inputValue.value : formValues[input.name] || ''}
onChange = {handleInputChange}
/>
</div>
);
})}
<button type = "submit">Submit</button>
</form>
);
};
export default DynamicForm;
Спасибо за ответ. В вашем примере есть только один массив объектов userData. У меня также есть другой массив объектов, который представляет собой поля ввода, поступающие из базы данных. Мне нужно соединить их вместе. Поэтому мне нужно сопоставить userData с полями ввода. Итак, скажем, из базы данных поступает 10 полей ввода. А в предыдущий визит пользователь ввел данные в 3 из них. Это будет страница редактирования, где мне нужно сопоставить пользовательские данные с полями ввода. Поля ввода могут меняться, поэтому они хранятся в базе данных, а не просто статичны.