【发布时间】:2016-10-23 07:05:17
【问题描述】:
如何将焦点设置在 material-ui TextField 组件上?
componentDidMount() {
ReactDom.findDomNode(this.refs.myControl).focus()
}
上面的代码我试过了,还是不行:(
【问题讨论】:
-
添加了another SO question的相关答案。
标签: material-ui
如何将焦点设置在 material-ui TextField 组件上?
componentDidMount() {
ReactDom.findDomNode(this.refs.myControl).focus()
}
上面的代码我试过了,还是不行:(
【问题讨论】:
标签: material-ui
您可以使用autoFocus 属性。
<TextField value="some value" autoFocus />
【讨论】:
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上检查超时是否仍然存在,如果存在则清除它。
inputRef 属性来设置焦点。见Material-ui doc
setTi... 时应该很清楚。就在那儿。 不要复制这个,看看AlienKevin的回答。
对于 React 16.8.6,您应该使用 TextField 的 inputRef 属性来设置焦点。我尝试了ref 属性,但它不起作用。
<TextField
inputRef={input => input && input.focus()}
/>
inputRef:使用此属性将 ref 回调传递给原生输入组件。
【讨论】:
null 的input 并且必须检查它。为什么我会收到null?
AlienKevin 是正确的(将 ref 回调传递给“TextField.inputProps”),但您也可以将元素引用保存在“this”对象上,以便稍后设置焦点。这是 Coffeescript 中的一个示例:
TextField
inputProps:
ref: (el)=>
if el?
@input_element = el
Button
onClick:=>
@input_element.focus()
【讨论】:
对于材质 ui TextField,您需要像这样在 inputProps 对象中输入 autoFocus 的道具。
<TextField inputProps={{ autoFocus: true }} />
【讨论】:
如果您正在使用 material-ui TextField 和 react 功能组件,您可以在 TextField 组件中传递 inputRef。这里的技巧是 if 条件 if(input != null)。
<TextField
variant="filled"
inputRef={(input) => {
if(input != null) {
input.focus();
}
}}
/>
这是一个适合您的工作示例。 CodeSandBox- Material-ui-TextFieldFocus
【讨论】:
这段代码实际上很好,但有一个缺点,每次渲染都会创建一个新函数。使用 useCallback 很容易解决
<TextField
inputRef={input => input && input.focus()}
/>
应该是
const callbackRef = useCallback((inputElement) => {
if (inputElement) {
inputElement.focus();
}
}, []);
...
<TextField
inputRef={callbackRef}
/>
【讨论】:
useCallback 不会阻止在每次渲染时创建新函数。它使callbackRef 的值始终是第一次渲染的函数,但所有其他渲染仍将创建不会被任何人使用的新函数。
这将在每次渲染时聚焦组件。我尝试的其他解决方案仅在初始时间聚焦元素。
const inputRef = React.useRef<HTMLInputElement>();
useEffect(() => {
inputRef.current?.focus();
}, [inputRef.current]);
const setTextInputRef = (element: HTMLInputElement) => {
inputRef.current = element;
};
return (
<TextField
inputRef={setTextInputRef}
/>
【讨论】:
我正在使用此解决方案,适用于受 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} />
}
【讨论】:
const handleClick = () => {
inputRef.current.firstChild.focus();
inputRef.current.firstChild.placeholder = '';
}
<InputBase
value={value}
ref={inputRef}
placeholder="search" />
<Button onClick={handleClick}>Click</Button>
【讨论】: