React: как создать динамические поля ввода, которые отображают пользовательские данные из базы данных

У меня есть динамические поля ввода, которые поступают из моей базы данных. создание полей ввода не является проблемой. однако, как только пользователь вводит информацию, он может захотеть вернуться и изменить ввод. У меня проблемы с компонентом редактирования. Кажется, что если я что-нибудь поставлю в свойство 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. ' Спасибо за помощь.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
0
61
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Базовый пример

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;

Спасибо за ответ. В вашем примере есть только один массив объектов userData. У меня также есть другой массив объектов, который представляет собой поля ввода, поступающие из базы данных. Мне нужно соединить их вместе. Поэтому мне нужно сопоставить userData с полями ввода. Итак, скажем, из базы данных поступает 10 полей ввода. А в предыдущий визит пользователь ввел данные в 3 из них. Это будет страница редактирования, где мне нужно сопоставить пользовательские данные с полями ввода. Поля ввода могут меняться, поэтому они хранятся в базе данных, а не просто статичны.

Good Stuff 01.02.2023 08:50
Ответ принят как подходящий

Я получил это из чата 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;
stackoverflow.com/help/gpt-policy
Robert Longson 12.02.2023 15:38

Другие вопросы по теме