首页 > 解决方案 > ReactJS - 动态创建表单字段组件,然后将这些字段中的数据保存到表单提交时的对象

问题描述

我是 React 的新手,事情进展顺利,但我在这个概念上陷入了非常严重的困境。我已经在这一点上待了几天,我认为我的大脑刚刚被所有新概念所淹没。

我的工作是帮助客户实施公司在他们的项目中出售的一些控制措施。我主要使用我们的 .NET 桌面内容。我的团队正在做一个辅助项目来创建基本上是 StrawPoll 的克隆,以便学习 React/Node/MongoDB 并在完整的开发生命周期中获得更多经验,因为我们所做的大部分工作只是小代码片段。

我已经设置了一些基本组件,但是在创建和使用动态创建的组件时我真的很困惑。如果有人可以告诉我该做什么或解释该做什么,我将非常感激。

你可以在这里找到我正在处理的分支:https ://github.com/TylerBarlock/gcCE-Survey/tree/poll-components-cont

我目前坚持的部分是 src/Components/Poll/PollCreate.js 和 PollCreateAnswerOption.js

PollCreate.js:

//Main component for poll creation

import React, { Fragment, useState, useRef } from "react";
import PollCreateAnswerOption from "./PollCreateAnswerOption";

const PollCreate = (props) => {
  // const [enteredTitle, setEnteredTitle] = useState("");
  // const [enteredDescription, setEnteredDescription] = useState("");
  const [enteredAnswer, setEnteredAnswer] = useState("");

  const [selectedPrivate, setSelectedPrivate] = useState("");
  const [selectedMultiple, setSelectedMultiple] = useState("");
  const [selectedLogin, setSelectedLogin] = useState("");
  const [selectedIpcheck, setSelectedIpcheck] = useState("");

  const enteredTitleRef = useRef();
  const enteredDescriptionRef = useRef();
  const enteredAnswerRef = useRef();

  const titleChangeHandler = (event) => {
    //setEnteredTitle(event.target.value);
  };

  const descriptionChangeHandler = (event) => {
    //setEnteredDescription(event.target.value);
  };

  const answerOptionChangeHandler = (answer) => {
    //setEnteredAnswer(answer);
  };

  const privateSelectedHandler = (event) => {
    setSelectedPrivate(event.target.value);
  };

  const multipleSelectedHandler = (event) => {
    setSelectedMultiple(event.target.value);
  };

  const loginSelectedHandler = (event) => {
    setSelectedLogin(event.target.value);
  };

  const ipcheckSelectedHandler = (event) => {
    setSelectedIpcheck(event.target.value);
  };

  const addAnswerOptionHandler = (event) => {
    console.log("add answer clicked");
  };

  const deleteAnswerOptionHandler = (event) => {
    console.log("delete clicked");
  };

  const onSubmitHandler = (event) => {
    //cancel default form submit behavior (reloads page)
    event.preventDefault();

    const enteredTitle = enteredTitleRef.current.value;
    const enteredDescription = enteredDescriptionRef.current.value;
    //const enteredAnswer = enteredAnswerRef.current.value;

    //object to hold all data about the new poll being created
    const newPollData = {
      title: enteredTitle,
      description: enteredDescription,
      answerOptions: [
        {
          id: enteredAnswer.id,
          text: enteredAnswer.text,
        },
      ],
      options: {
        private: selectedPrivate,
        multiple: selectedMultiple,
        login: selectedLogin,
        ipcheck: selectedIpcheck,
      },
    };
    //send the new poll data up to the Poll component
    props.onSaveNewPoll(newPollData);

    console.log(newPollData.title);
    console.log(newPollData.description);
    console.log(newPollData.answerOptions);
  };

  return (
    <React.Fragment>
      <form onSubmit={onSubmitHandler}>
        <h2 className="mb-4 text-center">Create a Poll</h2>
        <div className="text-left">
          <div className="grid grid-cols-1 mb-4">
            <h4 className="mb-2">Title</h4>
            <input
              type="text"
              placeholder="Ask your question..."
              onChange={titleChangeHandler}
              ref={enteredTitleRef}
            ></input>
          </div>
        </div>
        <div className="text-left">
          <div className="grid grid-cols-1 mb-4">
            <h4 className="mb-2">Description (optional)</h4>
            <input
              type="text"
              placeholder="Describe the poll..."
              onChange={descriptionChangeHandler}
              ref={enteredDescriptionRef}
            ></input>
          </div>
        </div>
        <div className="text-left">
          <div className="grid grid-cols-1 mb-2 formtext">
            <h4 className="mb-2">Answer Options</h4>
            <PollCreateAnswerOption
              onAnswerOptionChange={answerOptionChangeHandler}
              ref={enteredAnswerRef}
              onAnswerOptionDelete={deleteAnswerOptionHandler}
            />
            <div className="flex">
              <input
                type="text"
                className="mb-3 formtext w-full"
                placeholder="Add an answer..."
                onChange={answerOptionChangeHandler}
              ></input>
              <button
                className="btn-alt-onwhite p-1 h-9"
                type="button"
                onClick={deleteAnswerOptionHandler}
              >
                X
              </button>
            </div>
            <div className="flex">
              <input
                type="text"
                className="mb-3 formtext w-full"
                placeholder="Add an answer..."
                onChange={answerOptionChangeHandler}
              ></input>
              <button
                className="btn-alt-onwhite p-1 h-9"
                type="button"
                onClick={deleteAnswerOptionHandler}
              >
                X
              </button>
            </div>
          </div>
        </div>
        <button
          className="btn-primary mb-2"
          type="button"
          onClick={addAnswerOptionHandler}
        >
          Add Answer
        </button>
        <div className="text-left">
          <div className="grid grid-cols-1 mb-6">
            <h4 className="mb-2">Options</h4>
            <div className="flex items-center">
              <input
                type="checkbox"
                value=""
                className="mx-3"
                onChange={privateSelectedHandler}
              ></input>
              <p>Private (only via direct link)</p>
            </div>
            <div className="flex items-center">
              <input
                type="checkbox"
                value=""
                className="mx-3"
                onChange={multipleSelectedHandler}
              ></input>
              <p>Allow multiple choices</p>
            </div>
            <div className="flex items-center">
              <input
                type="checkbox"
                value=""
                className="mx-3"
                onChange={loginSelectedHandler}
              ></input>
              <p>Voters must log in to vote</p>
            </div>
            <div className="flex items-center">
              <input
                type="checkbox"
                value=""
                className="mx-3"
                onChange={ipcheckSelectedHandler}
              ></input>
              <p>Check for duplicate IP</p>
            </div>
          </div>
        </div>
        <button type="submit" className="btn-primary mx-2">
          Create Poll
        </button>
        <button type="button" className="btn-alt-onwhite mx-2">
          Advanced Settings
        </button>
      </form>
    </React.Fragment>
  );
};

export default PollCreate;

PollCreateAnswerOption.js:

import React, { useState, useRef } from "react";

const PollCreateAnswerOption = React.forwardRef((props, ref) => {
  const [enteredAnswerOption, setEnteredAnswerOption] = useState();

  const answerOptionChangeHandler = (event) => {
    setEnteredAnswerOption(event.target.value);
    props.onAnswerOptionChange(event.target.value);
  };

  const deleteAnswerOptionHandler = (event) => {
    props.onAnswerOptionDelete(event);
  };

  return (
    <div className="flex">
      <input
        type="text"
        className="mb-3 formtext w-full"
        placeholder="Add an answer..."
        onChange={answerOptionChangeHandler}
        ref={ref}
      ></input>
      <button
        className="btn-alt-onwhite p-1 h-9"
        type="button"
        onClick={deleteAnswerOptionHandler}
      >
        X
      </button>
    </div>
  );
});

export default PollCreateAnswerOption;

我对大多数表单都满意,但我对如何生成 3 个 PollCreateAnswerOption 组件、允许用户添加和删除 PollCreateAnswerOptions,然后将每个表单中的数据放入我的 newPollData 对象感到困惑。

如果代码令人困惑或难以阅读,我提前道歉。这里有很多东西是我尝试各种东西时实现的。我试图尽可能地清理它。

目前有 useState 和 useRef 钩子,因为我不知道我应该在这里使用哪个,而且我都搞砸了。

提前感谢任何看到这个的人!我真的很感谢你的帮助,我保证在此之前我做了很多谷歌搜索和阅读,但我的大脑此时只是被炒了......

标签: javascriptreactjs

解决方案


推荐阅读