当单击按钮时,如何使用useRef挂钩专注于Material UI TextField?

时间:2020-06-13 10:00:14

标签: reactjs material-ui react-hooks

我遇到的问题与How to focus a Material UI Textfield on button click?类似,但我无法通过提供的答案解决问题。

这是代码。基本上,所有文本字段都是禁用的。单击“编辑配置文件”按钮时,它将帐户名的disabled状态设置为false,我想重点关注该特定字段。我使用的是useRef钩子来引用该字段,但是它没有用。只有单击两次按钮,它才能使用。

import React, { useState, useEffect, useRef } from "react";
import Avatar from "@material-ui/core/Avatar";
import Button from "@material-ui/core/Button";
import CssBaseline from "@material-ui/core/CssBaseline";
import TextField from "@material-ui/core/TextField";
import Grid from "@material-ui/core/Grid";
import PermContactCalendarIcon from "@material-ui/icons/PermContactCalendar";
import Typography from "@material-ui/core/Typography";
import { makeStyles } from "@material-ui/core/styles";
import Container from "@material-ui/core/Container";
import Paper from "@material-ui/core/Paper";

const useStyles = makeStyles((theme) => ({
  paper: {
    marginTop: theme.spacing(3),
    padding: theme.spacing(5),
    display: "flex",
    flexDirection: "column",
    alignItems: "center",
  },
  avatar: {
    margin: theme.spacing(1),
    backgroundColor: theme.palette.secondary.main,
  },
  form: {
    width: "100%", // Fix IE 11 issue.
    marginTop: theme.spacing(3),
  },
  submit: {
    margin: theme.spacing(3, 0, 2),
  },
  fixedHeight: {
    height: 1000,
  },
  button: {
    marginTop: theme.spacing(3),
    marginRight: theme.spacing(3),
  },
}));

export default function AccountPage({ userdata }) {
  const classes = useStyles();

  const [accountName, setAccountName] = useState("");

  const [disabled, setDisabled] = useState(true);
  const inputRef = useRef(null);

  const handleOnChange = (e) => {
    if (e.target.name === "accountname") {
      setAccountName(e.target.value);
    }
  };

  return (
    <Container component="main">
      <CssBaseline />
      <Paper>
        <div className={classes.paper}>
          <Avatar className={classes.avatar}>
            <PermContactCalendarIcon />
          </Avatar>
          <Typography component="h1" variant="h5">
            Account & User Settings
          </Typography>
          <form className={classes.form} noValidate>
            <Grid
              container
              direction="column"
              justify="center"
              alignItems="stretch"
              spacing={2}
            >
              <Grid item xs={12}>
                <Typography color="primary" display="inline" noWrap>
                  Account Name :
                </Typography>
              </Grid>
              <Grid item xs={12}>
                <TextField
                  name="accountname"
                  variant="outlined"
                  fullWidth
                  //   autoFocus
                  onChange={handleOnChange}
                  disabled={disabled}
                  value={accountName}
                  inputRef={inputRef}
                />
              </Grid>
              <Grid item xs={12}>
                <Typography color="primary" display="inline" noWrap>
                  E-mail Address :
                </Typography>
              </Grid>
              <Grid item xs={12}>
                <TextField
                  variant="outlined"
                  fullWidth
                  value={userdata.email}
                  type="email"
                  name="email"
                  disabled={true}
                  //   onChange={handleOnChange}
                />
              </Grid>
              <Grid item xs={12}>
                <Typography color="primary" display="inline" noWrap>
                  Account ID :
                </Typography>
              </Grid>
              <Grid item xs={12}>
                <TextField
                  variant="outlined"
                  fullWidth
                  name="id"
                  value={userdata._id}
                  type="text"
                  disabled={true}
                  //   onChange={handleOnChange}
                />
              </Grid>
            </Grid>
            <Button
              variant="contained"
              color="primary"
              className={(classes.submit, classes.button)}
              onClick={() => {
                setDisabled(false);
                inputRef.current.focus();
              }}
            >
              Edit Profile
            </Button>
            <Button
              //   type="submit"
              variant="contained"
              color="primary"
              className={(classes.submit, classes.button)}
              onClick={() => {
                setDisabled(true);
              }}
            >
              Save Changes
            </Button>
          </form>
        </div>
      </Paper>
    </Container>
  );
}

1 个答案:

答案 0 :(得分:3)

问题出在“编辑”按钮的onClick事件处理程序中:

() => {
  setDisabled(false);
  inputRef.current.focus();
};

您应该记住setState是异步的。这是React docs的引文:

setState函数用于更新状态。它接受一个新的 状态值并入队重新渲染组件。

换句话说,React承诺在将来的某个时候将disabled设置为false,但是在执行行inputRef.current.focus()时可能不会。

因此,您要尝试执行的操作是问React:disabled设置为false时,聚焦一个元素。这就是useEffect钩子的作用-它使您可以执行副作用。因此,您可以像下面这样设置inputRef.current.focus()钩子,而不是将setDisabled(false)放在useEffect之后:

useEffect(() => {
  if (!disabled) {
    inputRef.current.focus();
  }
}, [disabled]); // Only run the function if disabled changes