反应钩子console.log和界面

时间:2019-12-19 20:50:22

标签: javascript reactjs react-hooks

在我问我的问题之前:是的,我确实阅读过其他每一篇有关此问题的文章,但是我基本上只是停留在上面,无法弄清楚如何解决此问题。

因此,基本上,我的呈现和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的使用状态,我尝试将其与回调结合使用以解决此问题,但它没有用。

我的问题基本上是: 我需要怎么做才能立即启用我的按钮而没有延迟? (也许还有其他我做错的事情?第一次使用react挂钩)

1 个答案:

答案 0 :(得分:3)

状态设置器(setSystem等)是异步的。这意味着您在做setSystem(event.target.value); checkFormFilled()之类的事情–在这种情况下,系统的新值在checkFormFilled运行时可能不会更新。这可能就是为什么您看到事物“落后于”值的原因。

您应该做的是在设置状态调用之后不直接调用checkFormFilled;而是将checkFormFilled放在取决于表单元素的useEffect挂钩中。这样,当这些值中的任何一个实际更新时,React就会调用您的checkFormFilled函数。

useEffect(() => {
    checkFormFilled();
}, [ticketname, description, prio, system]);

然后,您的变更处理程序只需要担心设置值,而无需调用表单填充检查,因此一切都保证是最新的。