我的应用中遇到这种情况:https://codesandbox.io/s/14mq9969j3
我的目标是通过单击GrandChildInput
中的div来专注于ChildInput
组件内部的输入。但是,当渲染ChildInput
时,this.childRef.current
的值为null
,一直保持不变,直到我通过单击将其手动聚焦在输入上为止。之后,将分配current
的值。
您可以在控制台中跟踪此转换。 this.childRef.current
日志只出现一次,但是在通过单击手动关注输入后,其值会更改。
我的最终目标是使StyledGrandChildInput以这种方式工作,但是作为中间步骤,我试图使未样式化的组件正常工作。我可以在本地项目中通过以下方式实现此结果(使用未样式化的组件):
但是,在通过上面的链接在CodeSandbox中使用项目中安装的版本进行工作时,由于某种原因,即使专注于非样式化的GrandChildInput组件也不起作用。
当我单击ChildInput的div
时,如何使应用程序专注于GrandChildInput组件?
答案 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。
答案 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>