【发布时间】:2020-04-27 20:30:08
【问题描述】:
我为我的问题制作了一个代码沙箱示例:https://codesandbox.io/s/react-form-submit-problem-qn0de。请尝试单击函数示例和类示例上的“+”/“-”按钮,您会看到不同之处。在函数示例中,我们总是在提交时获取之前的值。
我将在下面解释有关此示例的详细信息。
我们有一个像这样的反应组件
function Counter(props) {
return (
<>
<button type="button" onClick={() => props.onChange(props.value - 1)}>
-
</button>
{props.value}
<button type="button" onClick={() => props.onChange(props.value + 1)}>
+
</button>
<input type="hidden" name={props.name} value={props.value} />
</>
);
}
它包含两个按钮和一个数值。用户可以按“+”和“-”按钮更改数字。它还呈现一个输入元素,因此我们可以在 <form> 中使用它。
这就是我们使用它的方式
class ClassExample extends React.Component {
constructor(props) {
super(props);
this.state = {
value: 1,
lastSubmittedQueryString: ""
};
this.formEl = React.createRef();
}
handleSumit = () => {
if (this.formEl.current) {
const formData = new FormData(this.formEl.current);
const search = new URLSearchParams(formData);
const queryString = search.toString();
this.setState({
lastSubmittedQueryString: queryString
});
}
};
render() {
return (
<div className="App">
<h1>Class Example</h1>
<form
onSubmit={event => {
event.preventDefault();
this.handleSumit();
}}
ref={ref => {
this.formEl.current = ref;
}}
>
<Counter
name="test"
value={this.state.value}
onChange={newValue => {
this.setState({ value: newValue }, () => {
this.handleSumit();
});
}}
/>
<button type="submit">submit</button>
<br />
lastSubmittedQueryString: {this.state.lastSubmittedQueryString}
</form>
</div>
);
}
}
我们将<Counter> 组件呈现在<form> 中,并且希望在我们更改<Counter> 的值后立即提交此表单。但是,在 onChange 事件中,如果我们只是这样做
onChange={newValue => {
this.setState({ value: newValue });
this.handleSubmit();
}}
那么我们不会得到更新的值,可能是因为 React 没有同步运行 setState。因此,我们将this.handleSubmit() 放在 setState 的第二个参数回调中,以确保它在状态更新后执行。
但是在函数示例中,据我所知,在状态钩子中没有什么像 setState 的第二个参数回调函数。所以我们不能达到同样的目标。我们找到了两种解决方法,但我们对其中任何一种都不满意。
解决方法 1
我们尝试使用效果挂钩来监听值发生变化时,我们提交表单。
React.useEffect(() => {
handleSubmit();
}, [value])
但有时我们只需要更改值而不提交表单,我们希望仅在单击按钮更改值时才调用提交事件,因此我们认为应该放入按钮的 onChange 事件。
解决方法 2
onChange={newValue => {
setValue(newValue);
setTimeout(() => {
handleSubmit();
})
}}
这很好用。我们总能得到更新的值。但问题是我们不了解它的工作原理和原因,而且我们从未见过人们以这种方式编写代码。我们担心将来的 React 更新会破坏代码。
对于 looooooooong 的帖子感到抱歉,感谢您阅读我的故事。以下是我的问题:
- 解决方法 1 和 2 怎么样?函数示例有什么“最佳解决方案”吗?
- 我们做错了什么吗?例如,也许我们根本不应该使用隐藏输入来提交表单?
任何想法将不胜感激:)
【问题讨论】:
-
解决方法 1 不是解决方法。这是正确的方法。在 useEffect 中,第二个参数是一个包含其依赖项的数组。
-
解决方法 1 的唯一问题是,它不是将提交与点击事件相关联,而是将提交与状态更改相关联。有时我们可能需要在不提交表单的情况下更改状态(我知道这个要求听起来很奇怪,而且它可能不会真正发生)。
标签: reactjs