在组件渲染后,react如何设置聚焦在特定文本字段上?
文档似乎建议使用参考,例如:
在渲染函数的输入字段上设置ref="nameInput",然后调用:
this.refs.nameInput.getInputDOMNode().focus();
但是我该把它叫什么呢?我在几个地方试过了,但都不行。
在组件渲染后,react如何设置聚焦在特定文本字段上?
文档似乎建议使用参考,例如:
在渲染函数的输入字段上设置ref="nameInput",然后调用:
this.refs.nameInput.getInputDOMNode().focus();
但是我该把它叫什么呢?我在几个地方试过了,但都不行。
当前回答
要将焦点移动到新创建的元素上,您可以将元素的ID存储在状态中,并使用它来设置自动聚焦。如。
export default class DefaultRolesPage extends React.Component {
addRole = ev => {
ev.preventDefault();
const roleKey = this.roleKey++;
this::updateState({
focus: {$set: roleKey},
formData: {
roles: {
$push: [{
id: null,
name: '',
permissions: new Set(),
key: roleKey,
}]
}
}
})
}
render() {
const {formData} = this.state;
return (
<GridForm onSubmit={this.submit}>
{formData.roles.map((role, idx) => (
<GridSection key={role.key}>
<GridRow>
<GridCol>
<label>Role</label>
<TextBox value={role.name} onChange={this.roleName(idx)} autoFocus={role.key === this.state.focus}/>
</GridCol>
</GridRow>
</GridSection>
))}
</GridForm>
)
}
}
通过这种方式,没有任何文本框获得页面加载的焦点(就像我想要的那样),但是当你按下“添加”按钮来创建一个新记录时,那么这个新记录就会获得焦点。
由于autoFocus不会再次“运行”,除非组件重新挂载,所以我不必费心取消this.state.focus(即当我更新其他状态时,它不会一直窃取焦点)。
其他回答
这是正确的方法,如何自动对焦。当你使用callback而不是string作为ref value时,它会被自动调用。你得到了你的ref,而不需要使用getDOMNode触摸DOM
render: function() {
return <TextInput ref={(c) => this._input = c} />;
},
componentDidMount: function() {
this._input.focus();
},
请注意,这些答案对我来说都没有用material-ui TextField组件。如何将焦点设置为一个materialUI TextField?我费了好大劲才让它起作用:
const focusUsernameInputField = input => {
if (input) {
setTimeout(() => {input.focus()}, 100);
}
};
return (
<TextField
hintText="Username"
floatingLabelText="Username"
ref={focusUsernameInputField}
/>
);
本卡普的解决方案在打字稿
React 16.8 +功能组件- useFocus钩子
export const useFocus = (): [React.MutableRefObject<HTMLInputElement>, VoidFunction] => {
const htmlElRef = React.useRef<HTMLInputElement>(null);
const setFocus = React.useCallback(() => {
if (htmlElRef.current) htmlElRef.current.focus();
}, [htmlElRef]);
return React.useMemo(() => [htmlElRef, setFocus], [htmlElRef, setFocus]);
};
关注坐骑
如果你只是想在一个元素挂载(初始渲染)时聚焦它,简单使用autoFocus属性就可以了。
<input type="text" autoFocus />
动态焦点
要动态控制焦点,请使用通用函数对组件隐藏实现细节。
React 16.8 +功能组件- useFocus钩子
const FocusDemo = () => {
const [inputRef, setInputFocus] = useFocus()
return (
<>
<button onClick={setInputFocus} >
Focus
</button>
<input ref={inputRef} />
</>
)
}
const useFocus = () => {
const htmlElRef = useRef(null)
const setFocus = () => {htmlElRef.current && htmlElRef.current.focus()}
return [ htmlElRef, setFocus ]
}
完整的演示
React 16.3 +类组件-使用
class App extends Component {
constructor(props){
super(props)
this.inputFocus = utilizeFocus()
}
render(){
return (
<>
<button onClick={this.inputFocus.setFocus}>
Focus
</button>
<input ref={this.inputFocus.ref}/>
</>
)
}
}
const utilizeFocus = () => {
const ref = React.createRef()
const setFocus = () => {ref.current && ref.current.focus()}
return {setFocus, ref}
}
完整的演示
你不需要getInputDOMNode??在这种情况下……
当组件被挂载时,只需简单地获取ref和focus()它——componentDidMount…
import React from 'react';
import { render } from 'react-dom';
class myApp extends React.Component {
componentDidMount() {
this.nameInput.focus();
}
render() {
return(
<div>
<input ref={input => { this.nameInput = input; }} />
</div>
);
}
}
ReactDOM.render(<myApp />, document.getElementById('root'));