【问题标题】:How to set focus to a materialUI TextField?如何将焦点设置到materialUI TextField?
【发布时间】:2016-10-23 07:05:17
【问题描述】:

如何将焦点设置在 material-ui TextField 组件上?

componentDidMount() {
    ReactDom.findDomNode(this.refs.myControl).focus()
}

上面的代码我试过了,还是不行:(

【问题讨论】:

标签: material-ui


【解决方案1】:

您可以使用autoFocus 属性。

<TextField value="some value" autoFocus />

【讨论】:

  • 页面加载时有效,表单提交后无效。
  • @StefanBalan 是的,这仅在页面加载时有效。提交表单不会重新加载页面。在这种情况下,您可以通过编程方式设置自动对焦。
  • 这对我不起作用。我添加了属性,没有任何变化。文本字段不关注页面加载。只有我吗?
【解决方案2】:

autoFocus 也对我不起作用,也许是因为这是一个在顶级组件加载时未安装的组件。我必须做一些更复杂的事情才能让它工作:

function AutoFocusTextField(props) {
  const inputRef = React.useRef();

  React.useEffect(() => {
    const timeout = setTimeout(() => {
      inputRef.current.focus();
    }, 100);

    return () => {
      clearTimeout(timeout);
    };
  }, []);

  return <TextField inputRef={inputRef} {...props} />;
}

请注意,由于某种原因,如果没有setTimeout,它将无法工作。欲了解更多信息,请参阅https://github.com/callemall/material-ui/issues/1594

【讨论】:

  • 您应该检查输入是否在超时回调中可用。此代码可能会抛出。更好的办法是将setTimeout返回的id保存到组件并在componentWillUnmount上检查超时是否仍然存在,如果存在则清除它。
  • 你可以使用 this.setState({}, () => { input.focus() }) 代替 setTimeout
  • 对于 React 16.8.6,你应该使用 TextField 的 inputRef 属性来设置焦点。见Material-ui doc
  • 对于代码的作者来说,这是一个可恶的 hack 怎么不是很明显?输入setTi... 时应该很清楚。就在那儿。 不要复制这个,看看AlienKevin的回答。
【解决方案3】:

对于 React 16.8.6,您应该使用 TextField 的 inputRef 属性来设置焦点。我尝试了ref 属性,但它不起作用。

<TextField
  inputRef={input => input && input.focus()}
/>

Material-ui doc 说:

inputRef:使用此属性将 ref 回调传递给原生输入组件。

【讨论】:

  • 这是正确的解决方案。请记住, 是其他几个 Material 组件的组合,包括 等。
  • 正确答案非常简短,请添加一些最小的工作示例。
  • 这很好,但由于某种原因,有时我会得到nullinput 并且必须检查它。为什么我会收到null
  • 这行得通,但测试给出错误提示 - 超出了最大更新深度。当组件在 componentWillUpdate 或 componentDidUpdate 中重复调用 setState 时,可能会发生这种情况。 React 限制嵌套更新的数量以防止无限循环
  • @lazy.lizard 你现在肯定已经发现了,但这只是基本的 react refs:当组件挂载时,ref 值是一个 DOM 元素,但当组件卸载时它是 null。
【解决方案4】:

AlienKevin 是正确的(将 ref 回调传递给“TextField.inputProps”),但您也可以将元素引用保存在“this”对象上,以便稍后设置焦点。这是 Coffeescript 中的一个示例:

TextField
    inputProps:
        ref: (el)=>
            if el?
                @input_element = el

Button
    onClick:=> 
        @input_element.focus()

【讨论】:

    【解决方案5】:

    对于材质 ui TextField,您需要像这样在 inputProps 对象中输入 autoFocus 的道具。

     <TextField inputProps={{ autoFocus: true }} />
    

    【讨论】:

      【解决方案6】:

      如果您正在使用 material-ui TextField 和 react 功能组件,您可以在 TextField 组件中传递 inputRef。这里的技巧是 if 条件 if(input != null)

      <TextField
          variant="filled"
          inputRef={(input) => {
            if(input != null) {
               input.focus();
            }
          }}
      />
      

      这是一个适合您的工作示例。 CodeSandBox- Material-ui-TextFieldFocus

      【讨论】:

        【解决方案7】:

        这段代码实际上很好,但有一个缺点,每次渲染都会创建一个新函数。使用 useCallback 很容易解决

        <TextField
          inputRef={input => input && input.focus()}
        />
        

        应该是

        const callbackRef = useCallback((inputElement) => {
             if (inputElement) {
                 inputElement.focus();
             }
         }, []);
        ...
        <TextField
          inputRef={callbackRef}
        />
        

        【讨论】:

        • 使用useCallback 不会阻止在每次渲染时创建新函数。它使callbackRef 的值始终是第一次渲染的函数,但所有其他渲染仍将创建不会被任何人使用的新函数。
        【解决方案8】:

        这将在每次渲染时聚焦组件。我尝试的其他解决方案仅在初始时间聚焦元素。

          const inputRef = React.useRef<HTMLInputElement>();
          
          useEffect(() => {
            inputRef.current?.focus();
          }, [inputRef.current]);
        
          const setTextInputRef = (element: HTMLInputElement) => {
            inputRef.current = element;
          };
           
          return (
            <TextField
              inputRef={setTextInputRef}
            />
        

        【讨论】:

          【解决方案9】:

          我正在使用此解决方案,适用于受 https://gist.github.com/carpben/de968e377cbac0ffbdefe1ab56237573 启发的文本字段

          
          const useFocus = (): [any, () => void] => {
              const htmlElRef: MutableRefObject<any> = useRef<HTMLDivElement>();
              const setFocus = (): void => {
                  if (!htmlElRef || !htmlElRef.current) return
                  const div = htmlElRef.current as HTMLDivElement
                  if (!div) return
                  const input = div.querySelector("input")
                  if (input) input.focus()
              }
              return [htmlElRef, setFocus];
          };
          
          
          export function MyComp() {
            const [ref, setFocus] = useFocus()
            
            // use setFocus() to focus the input field
          
            return <Input ref={ref} />
          }
          
          

          【讨论】:

            【解决方案10】:
             const handleClick =  () => {
               inputRef.current.firstChild.focus();
               inputRef.current.firstChild.placeholder = '';
              }
              <InputBase
                    value={value}
                    ref={inputRef}
                    placeholder="search" />
                <Button onClick={handleClick}>Click</Button>
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2021-04-16
              • 1970-01-01
              • 2018-05-19
              • 1970-01-01
              • 1970-01-01
              • 2020-03-27
              • 2020-03-24
              • 1970-01-01
              相关资源
              最近更新 更多