如何等待使用Hooks更新状态。提交表单时,我需要在运行其他代码之前检查termsValidation
是否为假。如果状态刚刚改变,它就不会改变。
import React, { useState } from 'react';
export default function Signup() {
const [terms, setTerms] = useState('');
const [termsValidation, setTermsValidation] = useState(false);
function handleSubmit(e) {
e.preventDefault();
if (!terms) {
setTermsValidation(true);
} else {
setTermsValidation(false);
}
if (!termsValidation) {
console.log('run something here');
}
}
return (
<div>
<form>
<input type="checkbox" id="terms" name="terms" checked={terms} />
<button type="submit" onClick={handleSubmit}>
Sign up
</button>
</form>
</div>
);
}
答案 0 :(得分:0)
当然。像setTermsValidation
这样的状态更改是异步操作,这意味着它不是立即执行的,程序不会等待它。它会触发并忘记。因此,当您调用setTermsValidation(true)
时,程序将继续运行下一个块,而不是等待termValidation更改为true。因此,termsValidation仍然具有旧值。
您可以这样做
function handleSubmit(e) {
e.preventDefault();
if (!terms) {
setTermsValidation(true);
} else {
setTermsValidation(false);
// assuming you want to run something when termsvalidation turn to false
console.log('run something here');
}
}
或者最好使用钩子useEffect()
useEffect(() => {
if (!termsValidation) {
console.log('run something here');
}
}, [termsValidation]);
但是请小心,因为useEffect也会在初始渲染上运行。
答案 1 :(得分:0)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using LayoutSample.Models;
using LayoutSample.Presenters;
using LayoutSample.Views;
namespace LayoutSample
{
public partial class Form1 : Form, IFlowLabel
{
public Form1()
{
InitializeComponent();
}
string IFlowLabel.label
{
get
{
return flowLayoutPanel1.ToString();
}
set
{
if (flowLayoutPanel1.InvokeRequired)
{
flowLayoutPanel1.Invoke(new MethodInvoker(() =>
{
flowLayoutPanel1.Text = value;
}));
}
else
{
flowLayoutPanel1.Text = value;
}
}
}
private void Form1_Load(object sender, EventArgs e)
{
for (int i = 0; i < 100; i++)
{
Label label = new Label();
label.AutoSize = false;
label.Width = 50;
label.Text = i.ToString();
flowLayoutPanel1.Controls.Add(label);
}
DataPresenter presenter = new DataPresenter(this);
presenter.CalculateArea();
}
}
}
钩子是异步的,但没有useState
那样的回调API。如果要等待状态更新,则需要一个setState
钩子:
useEffect
答案 2 :(得分:0)
在这种情况下,不要忘记 useRef 作为一种可能性——useState 和 useEffect 当然有它们的位置,但是你跟踪和管理状态的逻辑可能有点麻烦,并且可能会导致不必要的重新——渲染您的组件(当该状态不构成渲染输出的一部分时)。作为来自 OP 的示例:
import React, { useState, useRef } from 'react';
export default function Signup() {
const [terms, setTerms] = useState('');
const termsValidation = useRef(false);
function handleSubmit(e) {
e.preventDefault();
if (!terms && !termsValidation.current) {
termsValidation.current = true;
console.log('run something here');
termsValidation.current = false; // when its finished running
}
}
return (
<div> etc
);
}