javascript - React 钩子 console.log 和接口
问题描述
在我问我的问题之前:是的,我确实阅读了有关此的所有其他文章,但我基本上只是卡住了,无法弄清楚如何解决这个问题。
所以基本上我的渲染和 console.log 比我的 useState 更改落后一步。视觉和功能上最大的问题是不能正确启用/禁用的动态按钮。我的代码是:
import React, { useState, useEffect } from 'react';
import ApiCalls from "../../classes/apiCallsClass"
import useStyles from "./styles";
import { TextField, Select, Paper, Grid, MenuItem, Button } from '@material-ui/core';
import { withStyles } from "@material-ui/styles";
export default function TicketCreation() {
const [buttonDisabled, setButtonDisabled] = useState(true);
const [, setTick] = useState(0);
const classes = useStyles();
const [ticketname, setTicketName] = useState('');
const [description, setDescription] = useState('');
const [prio, setPrio] = useState('');
const [system, setSystem] = useState('');
const handleChangePrio = event => {
setPrio(event.target.value);
checkFormFilled();
};
const handleChangeDescription = event => {
setDescription(event.target.value);
checkFormFilled();
};
const handleChangeName = event => {
setTicketName(event.target.value);
checkFormFilled();
};
const handleChangeSystem = event => {
setSystem(event.target.value);
checkFormFilled();
};
const checkFormFilled = () => {
if (ticketname && description && prio && system) {
setButtonDisabled(false, function(){
setTick(tick => tick + 1);
});
} else{
setButtonDisabled(true, function(){
setTick(tick => tick + 1);
});
}
}
const handelButtonSubmit = event => {
if (ApiCalls.createTicket(ticketname, system, prio, description)) {
console.log("Created");
}
}
return (
<div className={classes.root}>
<Grid container spacing={3}>
<Grid item xs={4}>
<Paper className={classes.paper}>
<TextField id="standard-basic" value={ticketname} onChange={handleChangeName} label="Ticketname" fullWidth />
</Paper>
</Grid>
<Grid item xs={4}>
<Paper className={classes.paper}>
<Select value={system} onChange={handleChangeSystem} displayEmpty fullWidth className={classes.selectEmpty}>
<MenuItem value="" disabled>
System
</MenuItem>
<MenuItem value={1}>Radar</MenuItem>
<MenuItem value={2}>Missles</MenuItem>
<MenuItem value={3}>Toilet</MenuItem>
</Select>
</Paper>
</Grid>
<Grid item xs={4}>
<Paper className={classes.paper}>
<Select value={prio} onChange={handleChangePrio} displayEmpty fullWidth className={classes.selectEmpty}>
<MenuItem value="" disabled>
Priority
</MenuItem>
<MenuItem value={1}>Low</MenuItem>
<MenuItem value={2}>Medium</MenuItem>
<MenuItem value={3}>High</MenuItem>
</Select>
</Paper>
</Grid>
<Grid item xs={12}>
<Paper className={classes.paper}>
<TextField
value={description}
onChange={handleChangeDescription}
id="outlined-multiline-static"
label="Ticket description"
multiline
rows="4"
variant="outlined"
fullWidth />
</Paper>
</Grid>
<Grid item xs={12}>
<Button disabled={buttonDisabled} onClick={handelButtonSubmit} variant="contained" color="primary">
Create
</Button>
</Grid>
</Grid>
</div>
);
}
不要介意 setTick 使用状态,我尝试将其与回调结合使用以解决问题,但它不起作用。
我的问题基本上是:我需要做什么才能立即启用我的按钮而不延迟?(也许我做错了其他事情?第一次使用反应钩子)
解决方案
状态设置器(setSystem 等)是异步的。这意味着您正在执行的操作,例如setSystem(event.target.value); checkFormFilled()
- 在这种情况下,系统的新值可能不会在 checkFormFilled 运行时更新。这可能就是为什么您会看到事物“落后于”价值观的原因。
您应该做的不是在设置状态调用后直接调用 checkFormFilled ;相反,将 checkFormFilled 放在一个useEffect
依赖于表单元素的钩子中。这样,当这些值中的任何一个实际更新时,React 将调用您的 checkFormFilled 函数。
useEffect(() => {
checkFormFilled();
}, [ticketname, description, prio, system]);
然后您的更改处理程序只需要担心设置值,而不是调用表单填充检查,并且一切都保证是最新的。
推荐阅读
- spring-boot - spring boot 不接 custmize trustManager
- mysql - (Amazon Linux) MySQL 在 EC2 重启时停止工作
- php - NGINX 总是强制下载 PHP 页面
- java - JOOQ 更新集不填充值
- sql - 使用限制性 where 子句(非常小的行子集)的内部连接的性能非常慢
- dojo - DoJo 增强的网格动态更新约束不起作用
- r - 无效的下标类型“列表”Azure 机器学习
- ios - '尝试将第 0 行插入第 0 节,但更新后第 0 节中只有 0 行' 向表中插入行时
- android - 使用 viewpager 进行圆形过渡的片段
- xml - XSLT 无法将 DITA 转换为新类型