React refs:无法读取null的属性“ focus”

时间:2018-10-27 16:13:08

标签: javascript reactjs styled-components

我的应用中遇到这种情况:https://codesandbox.io/s/14mq9969j3

我的目标是通过单击GrandChildInput中的div来专注于ChildInput组件内部的输入。但是,当渲染ChildInput时,this.childRef.current的值为null,一直保持不变,直到我通过单击将其手动聚焦在输入上为止。之后,将分配current的值。

您可以在控制台中跟踪此转换。 this.childRef.current日志只出现一次,但是在通过单击手动关注输入后,其值会更改。

我的最终目标是使StyledGrandChildInput以这种方式工作,但是作为中间步骤,我试图使未样式化的组件正常工作。我可以在本地项目中通过以下方式实现此结果(使用未样式化的组件):

  • 反应16.4.2
  • 样式化组件3.4.2

但是,在通过上面的链接在CodeSandbox中使用项目中安装的版本进行工作时,由于某种原因,即使专注于非样式化的GrandChildInput组件也不起作用。

当我单击ChildInput的div时,如何使应用程序专注于GrandChildInput组件?

2 个答案:

答案 0 :(得分:1)

当您尝试尝试使用ref将onClick处理程序分配给div时,它将尝试立即从ref访问handleFocus,但由于尚未将其分配给输入组件。其值将为null,因此您会收到该错误。

对于要打印的值,在控制台中正确无误,这与控制台如何评估该值有关。 This answer将对此提供更多详细信息

因此,为了解决您的问题,您需要做的是通过包装另一个函数来调用handleFocus函数,以便仅在单击时对其进行评估

<div
    onClick={() => this.childRef.current.handleFocus()}
    style={{ border: "1px solid black", padding: 5 }}
  >
    click me
    <GrandChildInput
      type="text"
      disabled
      focused
      length={5}
      ref={this.childRef}
    />
  </div>

此外,如果您想知道为什么您的方法行不通。这是因为没有什么原因导致render方法再次被调用,因此在分配了引用并可用之后,正确的函数才被分配给onClick。

Working CodeSandbox

答案 1 :(得分:0)

对于执行相同操作有困难,但是当GrandChildInput是styled-component并且4的版本低于{{1 }}。

通过他的实施,您可能会得到Uncaught TypeError: _this.childRef.current.handleFocus is not a function

在这种情况下,可以通过以下方式将样式组件上的ref属性重命名为innerRef

<div
onClick={() => this.childRef.current.handleFocus()}
style={{ border: "1px solid black", padding: 5 }}
>
  click me
  <StyledGrandChildInput
    type="text"
    disabled
    focused
    length={5}
    innerRef={this.childRef} // change
  />
</div>