我如何使用这个 React 组件来收集表单数据?
How can I use this React component to collect form data?
我创建了两个组件,它们共同创建了一个 'progressive' 样式的输入表单。我选择这种方法的原因是因为问题可能会更改文本或更改顺序,因此会从存储在名为 CustomerFeedback 的 JS 文件中的数组中提取到组件中。
到目前为止,我一直在尝试添加一个数据处理函数,该函数将在用户单击 'Proceed' 按钮时触发。该函数应收集所有呈现问题的所有答案,并将它们存储在名为 RawInputData 的数组中。我已经设法使用下面显示的代码使其在 SurveyForm 的硬编码版本中工作,但我还没有找到一种方法使其足够动态以与 SurveyQuestion 组件一起使用。谁能帮我让 dataHander 函数动态收集数据?
我做了什么:
https://codesandbox.io/s/angry-dew-37szi2?file=/src/InputForm.js:262-271
所以,我们可以让它变得更简单,您只需在从 props 调用处理程序时传递必要的数据即可:
const inputRef = React.useRef();
const handleNext = () => {
props.clickHandler(props.reference, inputRef.current.value);
};
并在 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)}
/>
所以,你想要数组(我认为对象更方便),如果你愿意,你可以像数组一样保存数据:
setInputData(prev => [...prev, value])
最初,我以为你想收集 InputForm 中按钮点击的数据,但显然你可以不用这个,这个解决方案更简单
UPD
使用 useImperativeHandle 的 Apouach:
如果我们想从我们的子组件中触发一些逻辑,我们应该在 forwarfRef+useImperativeHandle 的帮助下为此创建句柄:
const Question = React.forwardRef((props, ref) => {
const inputRef = React.useRef();
React.useImperativeHandle(
ref,
{
getData: () => ({
key: props.reference,
value: inputRef.current.value
})
},
[]
);
在此之后我们可以将所有 ref 保存在父组件中:
const questionRefs = React.useRef(
Array.from({ length: QuestionsText.length })
);
// ...
<Question
key={question.id}
ref={(ref) => (questionRefs.current[i] = ref)}
我们可以在需要时处理这些数据:
const handleComplete = () => {
setInputData(
questionRefs.current.reduce((acc, ref) => {
const { key, value } = ref.getData();
return {
...acc,
[key]: value
};
}, {})
);
};
在此处查看 ref 如何使用:
https://reactjs.org/docs/forwarding-refs.html
https://reactjs.org/docs/hooks-reference.html#useimperativehandle
我仍然强烈建议使用 react-hook-form 和嵌套表单来处理它
我创建了两个组件,它们共同创建了一个 'progressive' 样式的输入表单。我选择这种方法的原因是因为问题可能会更改文本或更改顺序,因此会从存储在名为 CustomerFeedback 的 JS 文件中的数组中提取到组件中。
到目前为止,我一直在尝试添加一个数据处理函数,该函数将在用户单击 'Proceed' 按钮时触发。该函数应收集所有呈现问题的所有答案,并将它们存储在名为 RawInputData 的数组中。我已经设法使用下面显示的代码使其在 SurveyForm 的硬编码版本中工作,但我还没有找到一种方法使其足够动态以与 SurveyQuestion 组件一起使用。谁能帮我让 dataHander 函数动态收集数据?
我做了什么:
https://codesandbox.io/s/angry-dew-37szi2?file=/src/InputForm.js:262-271
所以,我们可以让它变得更简单,您只需在从 props 调用处理程序时传递必要的数据即可:
const inputRef = React.useRef();
const handleNext = () => {
props.clickHandler(props.reference, inputRef.current.value);
};
并在 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)}
/>
所以,你想要数组(我认为对象更方便),如果你愿意,你可以像数组一样保存数据:
setInputData(prev => [...prev, value])
最初,我以为你想收集 InputForm 中按钮点击的数据,但显然你可以不用这个,这个解决方案更简单
UPD 使用 useImperativeHandle 的 Apouach: 如果我们想从我们的子组件中触发一些逻辑,我们应该在 forwarfRef+useImperativeHandle 的帮助下为此创建句柄:
const Question = React.forwardRef((props, ref) => {
const inputRef = React.useRef();
React.useImperativeHandle(
ref,
{
getData: () => ({
key: props.reference,
value: inputRef.current.value
})
},
[]
);
在此之后我们可以将所有 ref 保存在父组件中:
const questionRefs = React.useRef(
Array.from({ length: QuestionsText.length })
);
// ...
<Question
key={question.id}
ref={(ref) => (questionRefs.current[i] = ref)}
我们可以在需要时处理这些数据:
const handleComplete = () => {
setInputData(
questionRefs.current.reduce((acc, ref) => {
const { key, value } = ref.getData();
return {
...acc,
[key]: value
};
}, {})
);
};
在此处查看 ref 如何使用: https://reactjs.org/docs/forwarding-refs.html https://reactjs.org/docs/hooks-reference.html#useimperativehandle
我仍然强烈建议使用 react-hook-form 和嵌套表单来处理它