我的Web应用程序有一种间接填充文本字段的方法,由于它是多次单击(对于上下文,它是一个日历)和多个字段,因此我想向大家展示使用它们时要填写哪个字段单击下一步按钮。
我无法将焦点放在文本字段本身。这样一来,用户就可以离开他们所单击的界面。
我可以将其用于输入,但是无法使它适用于文本字段。具体来说,这是两套代码,我在哪里出错?
import React, { useState, useRef, useEffect } from "react";
import { makeStyles } from "@material-ui/core/styles";
import { Button, TextField } from "@material-ui/core";
const useStyles = makeStyles(theme => ({
root: {
"& > *": {
margin: theme.spacing(1)
}
}
}));
export default function Inputs() {
const classes = useStyles();
const [focused, setFocused] = useState(false);
const focusedRef = useRef();
const toggleFocusOnElement = () => {
setFocused(prevFocused => !prevFocused);
};
useEffect(() => {
if (focused) {
focusedRef.current.classList.add("Mui-focused");
} else {
focusedRef.current.classList.remove("Mui-focused");
}
}, [focused]);
return (
<>
<Button onClick={toggleFocusOnElement}>
{focused ? "Remove" : "Fake"} focus
</Button>
<form className={classes.root} noValidate autoComplete="off">
<TextField
inputRef={focusedRef}
defaultValue="Hello world"
inputProps={{ "aria-label": "description" }}
/>
</form>
</>
);
}
import React, { useState, useRef, useEffect } from "react";
import { makeStyles } from "@material-ui/core/styles";
import { Button, Input } from "@material-ui/core";
const useStyles = makeStyles(theme => ({
root: {
"& > *": {
margin: theme.spacing(1)
}
}
}));
export default function Inputs() {
const classes = useStyles();
const [focused, setFocused] = useState(false);
const focusedRef = useRef();
const toggleFocusOnElement = () => {
setFocused(prevFocused => !prevFocused);
};
useEffect(() => {
if (focused) {
focusedRef.current.classList.add("Mui-focused");
} else {
focusedRef.current.classList.remove("Mui-focused");
}
}, [focused]);
return (
<>
<Button onClick={toggleFocusOnElement}>
{focused ? "Remove" : "Fake"} focus
</Button>
<form className={classes.root} noValidate autoComplete="off">
<Input
ref={focusedRef}
defaultValue="Hello world"
inputProps={{ "aria-label": "description" }}
/>
</form>
</>
);
}
是否有解决此限制的方法,还是伪造焦点的更好方法?
答案 0 :(得分:1)
Mui-focused
类需要应用于contains the <input>
element的<div>
。 inputRef
道具在<input>
元素本身上添加了一个引用,而ref
上的Input
(无论是直接还是通过TextField InputProps)是placed on the containing div。>
我建议您完全不要为此使用refs或useEffect
,而应直接使用类名:
<TextField
InputProps={{ className: focused ? "Mui-focused" : undefined }}
defaultValue="Hello world"
/>
答案 1 :(得分:0)
InputRef={focusedRef}
和InputProps={{'ref':focusedRef}}
不同。import React, { useState, useRef, useEffect } from "react";
import { makeStyles } from "@material-ui/core/styles";
import { Button, TextField, Input } from "@material-ui/core";
const useStyles = makeStyles(theme => ({
root: {
"& > *": {
margin: theme.spacing(1)
}
}
}));
export default function Inputs() {
const classes = useStyles();
const [focused, setFocused] = useState(false);
const focusedRef = useRef();
const toggleFocusOnElement = () => {
setFocused(prevFocused => !prevFocused);
};
useEffect(() => {
if (focused) {
focusedRef.current.classList.add("Mui-focused");
} else {
focusedRef.current.classList.remove("Mui-focused");
}
}, [focused]);
return (
<>
<Button onClick={toggleFocusOnElement}>
{focused ? "Remove" : "Fake"} focus
</Button>
<form className={classes.root} noValidate autoComplete="off">
<TextField
InputProps={{ ref: focusedRef }}
defaultValue="Hello world"
/>
</form>
</>
);
}
我不确定为什么会这样,但是我可以在codeandbox中确认上面的代码对我有用。
答案 2 :(得分:-2)
我认为您应该只调用HTML控件的focus()
和blur()
方法。
这将自动使焦点移至元素或从元素移出焦点,并实现您想要实现的目标。
const toggleFocusOnElement = () => {
setFocused(prevFocused => !prevFocused);
if (focused) {
focusedRef.current.blur();
} else {
focusedRef.current.focus();
}
};