单击按钮时如何使用 useRef 挂钩关注 Material UI TextField?
Posted
技术标签:
【中文标题】单击按钮时如何使用 useRef 挂钩关注 Material UI TextField?【英文标题】:How to focus on Material UI TextField using useRef hooks when a button is clicked? 【发布时间】:2020-10-03 02:11:05 【问题描述】:我遇到了与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】:问题出在编辑按钮的 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
【讨论】:
再次感谢您的帮助!它现在可以工作,但我仍然对何时使用 useEffect 挂钩感到困惑。所以基本上,如果我们有超过 1 个函数,最好使用 useEffect 以免干扰主函数? 当由于状态改变而需要做一些动作时,你应该考虑使用useEffect
。这些操作可以是获取 API、更改 document.title 或聚焦元素等。我建议阅读有关 Using the Effect Hook 的 React 文档。以上是关于单击按钮时如何使用 useRef 挂钩关注 Material UI TextField?的主要内容,如果未能解决你的问题,请参考以下文章
“从不”类型上不存在属性“值”。在 mui 中使用 useRef 挂钩时
如何在使用redux格式按下下一个键盘按钮后如何使用useRef钩子来选择下一个TextInput
使用redux-form按下下一个键盘按钮后如何使用useRef钩子选择下一个TextInput