Answers:
您应该这样做,componentDidMount
而refs callback
不是。像这样
componentDidMount(){
this.nameInput.focus();
}
class App extends React.Component{
componentDidMount(){
this.nameInput.focus();
}
render() {
return(
<div>
<input
defaultValue="Won't focus"
/>
<input
ref={(input) => { this.nameInput = input; }}
defaultValue="will focus"
/>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react-dom.js"></script>
<div id="app"></div>
@Dhiraj的答案是正确的,为方便起见,您可以使用autoFocus道具在安装时让输入自动聚焦:
<input autoFocus name=...
请注意,在jsx中,它autoFocus
(大写F)与不区分大小写的普通旧html不同。
autofocus
,它不仅使用了HTML5不可靠的属性,而且实际上还用于focus()
DOM挂载中,react-dom
因此非常可靠。
从React 0.15开始,最简洁的方法是:
<input ref={input => input && input.focus()}/>
如果只想在挂载(初始渲染)时聚焦某个元素,则只需使用autoFocus属性即可。
<input type="text" autoFocus />
要动态控制焦点,请使用常规功能从组件中隐藏实现细节。
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 ]
}
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}
}
(htmlElRef.current as any).focus()
和(2)return {htmlElRef, setFocus}
而不是数组。
useFocus
多个元素,可能会出现问题。
useFocus
用打字稿写的。gist.github.com/carpben/de968e377cbac0ffbdefe1ab56237573
as const
您有),非常有教育意义!
set
放在第二个位置const [inputRef, setInputFocus] = useFocus()
。这与useState更匹配。首先是对象,然后是该对象的设置者
如果您只想在React中进行自动对焦,那很简单。
<input autoFocus type="text" />
如果您只是想知道将代码放在哪里,答案在componentDidMount()中。
v014.3
componentDidMount() {
this.refs.linkInput.focus()
}
在大多数情况下,您可以将引用附加到DOM节点,而完全避免使用findDOMNode。
在此处阅读API文档:https : //facebook.github.io/react/docs/top-level-api.html#reactdom.finddomnode
F
!(注意自我和他人,而不是回答者)。
React 16.3通过在组件的构造函数中创建一个ref并使用如下所示,添加了一种新的便捷方式来处理此问题:
class MyForm extends Component {
constructor(props) {
super(props);
this.textInput = React.createRef();
}
componentDidMount() {
this.textInput.current.focus(); // one important change here is that we need to access the element via current.
}
render() {
// instead of using arrow function, the created ref can be used directly.
return(
<div>
<input ref={this.textInput} />
</div>
);
}
}
有关更多详细信息,您可以查看本文在React博客中。
更新:
从React 16.8开始,useRef
可以在函数组件中使用hook来获得相同的结果:
import React, { useEffect, useRef } from 'react';
const MyForm = () => {
const textInput = useRef(null);
useEffect(() => {
textInput.current.focus();
}, []);
return (
<div>
<input ref={textInput} />
</div>
);
};
我刚遇到这个问题,并且我使用的是React 15.0.1 15.0.2,并且我使用的是ES6语法,但由于v.15在几周前就已删除,因此我并没有从其他答案中得到所需的东西和一些this.refs
属性已弃用并移除。
总的来说,我需要的是:
我在用着:
我在页面autoFocus={true}
的第一个<input />
上使用过,以便在装入组件时将其聚焦。
这花费了更长的时间并且更加令人费解。我保留与简洁解决方案无关的代码。
我需要一个全局状态来知道是否应该设置焦点并在设置焦点时将其禁用,因此当组件重新渲染时,我不会一直保持焦点设置(我将使用 componentDidUpdate()
用来检查设置焦点。 )
可以按照您认为适合自己的应用程序进行设计。
{
form: {
resetFocus: false,
}
}
该组件将需要具有 resetfocus
最终将焦点放在自身上,设置属性和一个CallBack来清除该属性。
另请注意,由于我的项目相当大,我将动作创建者组织到单独的文件中,并且我想将它们分解为更易于管理的块。
import { connect } from 'react-redux';
import MyField from '../presentation/MyField';
import ActionCreator from '../actions/action-creators';
function mapStateToProps(state) {
return {
resetFocus: state.form.resetFocus
}
}
function mapDispatchToProps(dispatch) {
return {
clearResetFocus() {
dispatch(ActionCreator.clearResetFocus());
}
}
}
export default connect(mapStateToProps, mapDispatchToProps)(MyField);
import React, { PropTypes } form 'react';
export default class MyField extends React.Component {
// don't forget to .bind(this)
constructor(props) {
super(props);
this._handleRef = this._handleRef.bind(this);
}
// This is not called on the initial render so
// this._input will be set before this get called
componentDidUpdate() {
if(!this.props.resetFocus) {
return false;
}
if(this.shouldfocus()) {
this._input.focus();
this.props.clearResetFocus();
}
}
// When the component mounts, it will save a
// reference to itself as _input, which we'll
// be able to call in subsequent componentDidUpdate()
// calls if we need to set focus.
_handleRef(c) {
this._input = c;
}
// Whatever logic you need to determine if this
// component should get focus
shouldFocus() {
// ...
}
// pass the _handleRef callback so we can access
// a reference of this element in other component methods
render() {
return (
<input ref={this._handleRef} type="text" />
);
}
}
Myfield.propTypes = {
clearResetFocus: PropTypes.func,
resetFocus: PropTypes.bool
}
通常的想法是,每个可能有错误并被关注的表单域都需要检查自身,以及是否需要将焦点放在自身上。
需要确定业务逻辑来确定给定字段是否是要重点关注的正确字段。由于依赖于各个应用程序,因此未显示。
提交表单时,该事件需要将全局焦点标志设置resetFocus
为true。然后,当每个组件更新自身时,它将看到它应该检查以查看是否获得焦点,如果是,则调度该事件以重置焦点,以便其他元素不必继续检查。
编辑
作为一个附带说明,我将业务逻辑保存在“实用程序”文件中,我只是导出了该方法,并在每个shouldfocus()
方法中对其进行了调用。
干杯!
现在,React文档对此有一个部分。https://facebook.github.io/react/docs/more-about-refs.html#the-ref-callback-attribute
render: function() {
return (
<TextInput
ref={function(input) {
if (input != null) {
input.focus();
}
}} />
);
},
autofocus
挂载,只需要寻找输入值时保持焦点的元素即可。在这种情况下,这非常适合。(使用react 15)
这不再是最佳答案。从v0.13 this.refs
版本开始componentDidMount()
,在某些奇怪的情况下,AFTER 运行之前可能不可用。
只需将autoFocus
标签添加到您的输入字段中,如上面的FakeRainBrigand所示。
<input autofocus>
字段的表现
<input>
参考 @Dave对@Dhiraj答案的评论;一种替代方法是在要渲染的元素上使用ref属性的回调功能(在组件首次渲染之后):
<input ref={ function(component){ React.findDOMNode(component).focus();} } />
Uncaught TypeError: Cannot read property 'focus' of null
component && React.findDomNode...
。:了解更多关于在这里facebook.github.io/react/docs/...
这是自动对焦的正确方法。当使用回调而不是字符串作为参考值时,将自动调用它。您可以获得参考,而不需要使用来接触DOM。getDOMNode
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}
/>
);
focus()
必须延迟到动画结束。
你不需要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'));
AutoFocus最适合我。我需要双击将某些文本更改为带有该文本的输入,所以最终得到的结果是:
<input autoFocus onFocus={this.setCaretToEnd} value={this.state.editTodo.value} onDoubleClick={this.updateTodoItem} />
注:要解决React将插入号放置在文本开头的问题,请使用以下方法:
setCaretToEnd(event) {
var originalText = event.target.value;
event.target.value = '';
event.target.value = originalText;
}
在这里找到:https : //coderwall.com/p/0iz_zq/how-to-put-focus-at-the-end-of-an-input-with-react-js
最简单的答案是在输入文本元素中添加ref =“ some name”并调用以下函数。
componentDidMount(){
this.refs.field_name.focus();
}
// here field_name is ref name.
<input type="text" ref="field_name" />
要将焦点移到新创建的元素上,可以将元素的ID存储在状态中,并使用它来设置autoFocus
。例如
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
(即在更新其他状态时,它将不会继续窃取焦点)。
在尝试了许多以上选项但没有成功之后,我发现它是我原来的样子disabling
,然后enabling
输入导致焦点丢失。
我有一个道具sendingAnswer
,可以在轮询后端时禁用输入。
<Input
autoFocus={question}
placeholder={
gettingQuestion ? 'Loading...' : 'Type your answer here...'
}
value={answer}
onChange={event => dispatch(updateAnswer(event.target.value))}
type="text"
autocomplete="off"
name="answer"
// disabled={sendingAnswer} <-- Causing focus to be lost.
/>
一旦我移除了禁用的道具,一切都会重新开始。
由于此错误的原因很多,我认为我也应该发布我所面临的问题。对我来说,问题在于我将输入内容作为另一个组件的内容来呈现。
export default ({ Content }) => {
return (
<div className="container-fluid main_container">
<div className="row">
<div className="col-sm-12 h-100">
<Content /> // I rendered my inputs here
</div>
</div>
</div>
);
}
这就是我调用上述组件的方式:
<Component Content={() => {
return (
<input type="text"/>
);
}} />
根据更新的语法,可以使用 this.myRref.current.focus()