我为问题创建了一个代码沙箱示例: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的帖子表示抱歉,感谢您阅读我的故事。这是我的问题:
任何想法都会感激:)
答案 0 :(得分:0)
您可以在this.handleSubmit()
中呼叫componentDidUpdate()
吗?
由于您的计数器已绑定到value
状态,因此如果状态发生变化,它应该重新呈现。
componentDidUpdate(prevProps, prevState) {
if (this.state.value !== prevState.value) {
this.handleSubmit();
}
}
这确保仅在value
状态更改时(setState完成后)才触发提交