我创建了两个组件,它们共同创建了一个“渐进式”风格的输入表单。我选择这种方法的原因是因为问题可能会更改文本或更改顺序,因此会从存储在名为 CustomerFeedback 的 JS 文件中的数组中拉入组件中。
到目前为止,我一直在尝试添加一个数据处理函数,当用户单击“继续”按钮时将触发该函数。该函数应该从所有呈现的问题中收集所有答案,并将它们 store 收集到一个名为 RawInputData 的数组中。我已经设法使用下面显示的代码使其在 SurveyForm 的硬编码版本中工作,但我还没有找到一种方法使其足够动态以与 SurveyQuestion 组件一起使用。谁能帮我让dataHander函数动态收集数据?
回答1
我做了什么:
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 中收集有关按钮单击的数据,但显然您可以不这样做,这个解决方案更简单
使用 useImperativeHandle 的 UPD Apouach:如果我们想从子组件触发一些逻辑,我们应该在 forwardRef+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.htmlhttps://reactjs.org/docs/hooks-reference.html#useimperativehandle
我仍然强烈建议使用带有嵌套表单的 react-hook-form 来处理它