如何通过单击按钮伪造对Material-ui TextField的关注?

时间:2020-02-24 17:04:55

标签: javascript reactjs material-ui

我的Web应用程序有一种间接填充文本字段的方法,由于它是多次单击(对于上下文,它是一个日历)和多个字段,因此我想向大家展示使用它们时要填写哪个字段单击下一步按钮。

我无法将焦点放在文本字段本身。这样一来,用户就可以离开他们所单击的界面。

我可以将其用于输入,但是无法使它适用于文本字段。具体来说,这是两套代码,我在哪里出错?

TextField(不起作用)

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>
    </>
  );
}

Edit Material demo

输入(有效)

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>
    </>
  );
}

Edit Material demo

是否有解决此限制的方法,还是伪造焦点的更好方法?

3 个答案:

答案 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"
        />

Edit Fake TextField focus

答案 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>
    </>
  );
}

Edit Material demo

我不确定为什么会这样,但是我可以在codeandbox中确认上面的代码对我有用。

答案 2 :(得分:-2)

我认为您应该只调用HTML控件的focus()blur()方法。 这将自动使焦点移至元素或从元素移出焦点,并实现您想要实现的目标。

const toggleFocusOnElement = () => {
    setFocused(prevFocused => !prevFocused);
    if (focused) {
      focusedRef.current.blur();
    } else {
      focusedRef.current.focus();
    }
};