简体   繁体   English

如何使用这个 React 组件来收集表单数据?

[英]How can I use this React component to collect form data?

I've created two components which together create a 'progressive' style input form.我创建了两个组件,它们共同创建了一个“渐进式”风格的输入表单。 The reason I've chosen this method is because the questions could change text or change order and so are being pulled into the component from an array stored in a JS file called CustomerFeedback.我选择这种方法的原因是因为问题可能会更改文本或更改顺序,因此会从存储在名为 CustomerFeedback 的 JS 文件中的数组中拉入组件中。

So far I've been trying to add a data handler function which will be triggered when the user clicks on the 'Proceed' button.到目前为止,我一直在尝试添加一个数据处理函数,当用户单击“继续”按钮时将触发该函数。 The function should collect all of the answers from all of the rendered questions and store them in an array called RawInputData.该函数应该从所有呈现的问题中收集所有答案,并将它们存储在一个名为 RawInputData 的数组中。 I've managed to get this to work in a hard coded version of SurveyForm using the code shown below but I've not found a way to make it dynamic enough to use alongside a SurveyQuestion component.我已经设法使用下面显示的代码在硬编码版本的 SurveyForm 中工作,但我还没有找到一种方法使它足够动态以与 SurveyQuestion 组件一起使用。 Can anybody help me make the dataHander function collect data dynamically?谁能帮我让dataHander函数动态收集数据?

There what I have done:我做了什么:

https://codesandbox.io/s/angry-dew-37szi2?file=/src/InputForm.js:262-271 https://codesandbox.io/s/angry-dew-37szi2?file=/src/InputForm.js:262-271

So, we can make it easier, you just can pass necessary data when call handler from props:所以,我们可以让它变得更简单,你可以在从 props 调用处理程序时传递必要的数据:

  const inputRef = React.useRef();

  const handleNext = () => {
    props.clickHandler(props.reference, inputRef.current.value);
  };

And merge it at InputForm component:并将其合并到 InputForm 组件中:

  const [inputData, setInputData] = useState({});

  const handler = (thisIndex) => (key, value) => {
    if (thisIndex === currentIndex) {
      setCurrentIndex(currentIndex + 1);
      setInputData((prev) => ({
        ...prev,
        [key]: value
      }));
    }
  };

  // ...
    <Question
        // ...
        clickHandler={handler(question.index)}
      />

So, you wanted array (object more coninient I think), you can just save data like array if you want:所以,你想要数组(我认为对象更方便),如果你愿意,你可以像数组一样保存数据:

setInputData(prev => [...prev, value])

Initially, I thought you want to collect data on button clicks in the InputForm, but apparently you can do without this, this solution is simpler最初,我以为您想在 InputForm 中收集有关按钮单击的数据,但显然您可以不这样做,这个解决方案更简单

UPD Apouach which use useImperativeHandle: If we want to trigger some logic from our child components we should create handle for this with help of forwarfRef+useImperativeHandle:使用 useImperativeHandle 的UPD Apouach:如果我们想从子组件触发一些逻辑,我们应该在 forwarfRef+useImperativeHandle 的帮助下为此创建句柄:

const Question = React.forwardRef((props, ref) => {
  const inputRef = React.useRef();

  React.useImperativeHandle(
    ref,
    {
      getData: () => ({
        key: props.reference,
        value: inputRef.current.value
      })
    },
    []
  );

After this we can save all of our ref in parent component:在此之后,我们可以将所有 ref 保存在父组件中:

  const questionRefs = React.useRef(
    Array.from({ length: QuestionsText.length })
  );

  // ...

  <Question
     key={question.id}
     ref={(ref) => (questionRefs.current[i] = ref)}

And we can process this data when we want:我们可以在需要时处理这些数据:

  const handleComplete = () => {
    setInputData(
      questionRefs.current.reduce((acc, ref) => {
        const { key, value } = ref.getData();
        return {
          ...acc,
          [key]: value
        };
      }, {})
    );
  };

See how ref uses here: https://reactjs.org/docs/forwarding-refs.html https://reactjs.org/docs/hooks-reference.html#useimperativehandle在此处查看 ref 如何使用: https ://reactjs.org/docs/forwarding-refs.html https://reactjs.org/docs/hooks-reference.html#useimperativehandle

I still strongly recommend use react-hook-form with nested forms for handle it我仍然强烈建议使用带有嵌套表单的 react-hook-form 来处理它

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM