我遇到的问题与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>
);
}
答案 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