【问题标题】:How to use React refs to focus a Redux Form field?如何使用 React refs 来聚焦 Redux Form 字段?
【发布时间】:2017-07-16 11:57:57
【问题描述】:

我正在尝试使用 React refs 在 Redux-Form Field 挂载时对其进行聚焦。

当我在componentDidMount 中尝试this.refs.title.getRenderedComponent().focus() 时,会抛出一个错误:

edit_fund.js:77 Uncaught TypeError: Cannot read property 'getRenderedComponent' of undefined

当我 console.log this.refs 时,它主要是一个空对象,有时将 'title' 标识为 ref,但它并不可靠。

我是否错误地使用了 refs?我的代码如下供参考。

componentDidMount = () => {
  this.refs.title
  .getRenderedComponent()
  .focus();
}

...

 <Field
    id="title"
    name="title"
    component={FormInput}
    type="text"
    ref="title" withRef
 />

【问题讨论】:

  • 这很奇怪,你的代码看起来很好,请显示整个组件代码
  • 你解决了吗?
  • 不,很遗憾从未解决过。
  • 我得到了类似于这个工作的东西如果组件类型是一个简单的类型,比如input。用户定义的组件会产生 refs,但它们不是支持像 focus() 这样的调用的 DOM 元素。相反,它们是 React 元素。

标签: javascript reactjs redux-form react-redux-form


【解决方案1】:

请尝试使用回调函数设置 ref:

ref={(input) => { this.title = input; }}

然后使用它来获取底层 DOM 节点:

ReactDOM.findDOMNode(this.title).focus();

如果 DOM 输入元素被包裹在另一个元素中:

ReactDOM.findDOMNode(this.title).getElementsByTagName("input")[0].focus()

根据 React 文档,使用带有字符串的 refs 有一些问题。详情请查看docs

【讨论】:

  • 如果 redux 表单定义在功能组件而不是类中怎么办?
【解决方案2】:

我使用 redux-form 和 Material UI 并且必须执行以下操作。 MaterialCheckboxFieldMaterialTextField 是我的项目中包装 material-ui/{Checkbox,TextField} 的自定义组件。

我将MaterialTextField转换为类组件(在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);
  }}
/>

Material UI 特定
建议使用来自this SO questionsetTimeout() 允许宽限期。考虑@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 UI 0.x,不知道是不是这个原因 React.CreateRef() 对我不起作用(推荐的方法 since React 16.3)。

【讨论】:

  • 我已经尝试过您的解决方案它可以工作,但是我无法将下一个文本框卡在单个输入框上。请帮帮我。
  • const node = findDOMNode(refs); if (node) { node.focus() }
猜你喜欢
  • 2021-06-14
  • 1970-01-01
  • 1970-01-01
  • 2017-09-12
  • 1970-01-01
  • 2018-05-04
  • 2017-08-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多