简体   繁体   English

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

[英]React refs: Cannot read property 'focus' of null

I have this situation in my app: https://codesandbox.io/s/14mq9969j3我的应用程序中有这种情况: https ://codesandbox.io/s/14mq9969j3

My goal is to be able to focus on input inside GrandChildInput component by clicking on div in ChildInput .我的目标是能够通过单击ChildInput中的 div 来专注于GrandChildInput组件内的输入。 However, when ChildInput gets rendered, the value of this.childRef.current is null , and it remains so until I manually focus on input by clicking into it.但是,当ChildInput被渲染时, this.childRef.current的值为null ,并且在我通过单击手动关注输入之前一直如此。 After that, the value of current is being assigned.之后,将分配current的值。

You can track this transformation in the console.您可以在控制台中跟踪此转换。 The this.childRef.current log appears once, but its value changes after manually focusing on input by clicking on it. this.childRef.current日志出现一次,但在通过单击手动关注输入后其值会发生变化。

My end goal is to have the StyledGrandChildInput work this way, but as an intermediary step, I am trying to make the unstyled component work.我的最终目标是让 StyledGrandChildInput 以这种方式工作,但作为中间步骤,我试图让无样式的组件工作。 I am able to achieve this result (with unstyled component) in my local project with:我能够在我的本地项目中实现这个结果(使用无样式的组件):

  • React 16.4.2反应 16.4.2
  • Styled-Components 3.4.2样式化组件 3.4.2

But when it comes to working in CodeSandbox with the versions that are installed in the project through the link above, for some reason even focusing on non-styled GrandChildInput component does not work.但是,当涉及到通过上面的链接在项目中安装的版本的 CodeSandbox 中工作时,出于某种原因,即使专注于非样式化的 GrandChildInput 组件也不起作用。

How can I make the app focus on GrandChildInput component when I click on div of ChildInput?单击 ChildInput 的div时,如何使应用程序专注于 GrandChildInput 组件?

When you try try to assign the onClick handler to the div using the ref, it will try to immediately access handleFocus from ref, but since it not yet assigned to the input component.当您尝试使用 ref 将 onClick 处理程序分配给 div 时,它将尝试立即从 ref 访问 handleFocus,但由于它尚未分配给输入组件。 Its value will be null and hence you get that error.它的值将为空,因此您会收到该错误。

As far as the value being printed, correct in the console, it has to do with how console evaluates the value.至于打印的值,在控制台中是正确的,它与控制台如何评估值有关。 This answer will provide more details on that This answer将提供更多细节

So in order to solve your problem, what you need to do is to call the handleFocus function by wrapping in another function so that its evaluated only on click like因此,为了解决您的问题,您需要做的是通过包装在另一个函数中来调用 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>

Also if you are wondering why your way did not work.另外,如果您想知道为什么您的方式不起作用。 Its because nothing caused the render method to be called again, so that the correct function was assigned to onClick after the ref has been assigned and available.这是因为没有任何东西导致再次调用 render 方法,因此在 ref 已分配并可用后,将正确的函数分配给 onClick。

Working CodeSandbox工作代码沙盒

To add up to @ShubhamKhatri 's answer for those who is having difficulties performing the same operation, but when GrandChildInput is a styled-component and the version of styled-component is below 4 .加起来@ShubhamKhatri的答案对于那些谁是有执行相同的操作困难,但是当GrandChildInput是一个styled-component和版本styled-component低于4

With his implementation, you might be getting Uncaught TypeError: _this.childRef.current.handleFocus is not a function .使用他的实现,您可能会收到Uncaught TypeError: _this.childRef.current.handleFocus is not a function

In this case, rename the ref property on a styled-component to be innerRef this way:在这种情况下,通过这种方式将样式组件上的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>

Please give React.forwardRef() a read.请阅读React.forwardRef()

This allows to pass refs from parent downwards as a secondary parameter (where the first parameter are the props).这允许从父级向下传递 refs 作为辅助参数(其中第一个参数是道具)。 It doesn't help much in reverse however... that's what I'm currently struggling with lol...然而,它并没有太大帮助......这就是我目前正在努力解决的问题......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM