我正在尝试使用React refs在安装时聚焦Redux-Form字段。
当我在this.refs.title.getRenderedComponent().focus()
中尝试componentDidMount
时,会抛出错误说:
edit_fund.js:77 Uncaught TypeError: Cannot read property 'getRenderedComponent' of undefined
当我在console.log中显示this.refs时,它主要是一个空对象,有时会识别出标题'作为一个参考,但它是不可靠的。
我是否正确使用裁判?我的代码在下面供参考。
componentDidMount = () => {
this.refs.title
.getRenderedComponent()
.focus();
}
...
<Field
id="title"
name="title"
component={FormInput}
type="text"
ref="title" withRef
/>
答案 0 :(得分:7)
请尝试使用回调功能设置参考:
ref={(input) => { this.title = input; }}
然后使用它来获取底层DOM节点:
ReactDOM.findDOMNode(this.title).focus();
如果DOM输入元素包含在另一个元素中,则:
ReactDOM.findDOMNode(this.title).getElementsByTagName("input")[0].focus()
根据React docs使用带有字符串的refs有一些问题。请查看docs了解详情。
答案 1 :(得分:0)
我使用redux-form和Material UI,并且必须执行以下操作。 MaterialCheckboxField
和MaterialTextField
是我的项目中包装material-ui/{Checkbox,TextField}
的自定义组件。
我将MaterialTextField
转换为 class组件(根据React docs的规定)。
您不能在 function 组件上使用
ref
属性,因为它们没有实例。
import { findDOMNode } from "react-dom";
字段设置焦点(在render()
方法内):
<Field
component={MaterialCheckboxField}
label="Checkbox"
name="..."
onClick={event => {
if (!event.target.checked) return;
// focus() field after grace period
// oddity of Material UI, does not work without
window.setTimeout(() => this.textField.focus(), 150);
}}
/>
特定于材料的用户界面
建议使用this SO question中的setTimeout()
允许宽限期。考虑@Lukas的评论:”此代码可能会抛出。更好的做法是将
setTimeout()
返回的ID保存到组件中,然后componentWillUnmount()
检查超时是否仍然存在并清除 如果是这样的话
将获得焦点的字段(在render()
方法内):
<Field
component={MaterialTextField}
label="Text field"
name="..."
ref={ref => {
const node = findDOMNode(ref);
if (node) {
// Material UI wraps input element,
// use querySelector() to obtain reference to it
// if not using MUI, querySelector() likely not needed
this.textField = node.querySelector("input");
}
}}
withRef
/>
注意
我正在使用Material UI0.x
,不确定这是为什么React.CreateRef()
对我不起作用(推荐的方法 since React 16.3。