class App extends React.PureComponent {
constructor(props) {
super(props);
this.test = React.createRef();
}
handleClick = () => alert(this.test.current.value)
render() {
return (
<div className="App">
<input ref={this.test} />
<button onClick={this.handleClick}>Get Value</button>
</div>
)
}
}
我知道这不是 OP 问题的解决方案,但对于那些从 Google 搜索而来的人来说,ref.current 可能为 null 的一种方式是将其附加到的组件是连接的组件,就像使用 react-redux connect 或 withRouter。对于 react-redux,解决方案是在 connect 的第四个选项中传递 forwardRef:true。
React.createRef()是异步的,所以如果您尝试在componentDidMount中访问ref,则会返回null,稍后会返回引用的组件的属性。
componentDidMount(): void {
if (this.viewShot && this.viewShot.current) {
this.viewShot.current.capture().then((uri) => {
console.log('do something with ', uri);
});
}
}
这是在此情境下使用React.createRef()的正确方式。
你缺少了 ref={this.test}
属性。
return (
<div className="App" ref={this.test}>
current value : {this.test.current + ""}
</div>
);
this.test
。
<Component ref={this.test} />
connect
方法中,因此this.test.current
会返回null ,因为它指向Redux包装器,要使此类组件有效,请将 forwardRef:true
即:
connect(mapStateToProps, mapDispatchToProps, null, {forwardRef: true})(Component)
withRouter
和connect
,则这里会有两个wrapper而不是一个,因此this.test.current
显然将返回null ,要克服这一点,请确保withRouter
包装connect
withRouter(connect(mapStateToProps, mapDispatchToProps, null, {forwardRef: true})(Component))
然后
<Component wrappedComponentRef={ref => this.test = ref} />
wrappedComponentRef
是用于使包装组件可用的属性, 就像forwardRef:true
一样,您可以在文档这里找到它。
在 React 的版本 17.0.2 中,引用(refs)和异步方面有所变化。在更新之后,像下面这样的代码就不能正常工作了:
import {useRef} from 'react';
import './kind.css'
const Kind = ({prop}) => {
// defining the ref
const kindRef = useRef('')
// print the ref to the console
console.log(kindRef)
return (
<div ref={kindRef} className="kind-container" >
<div className="kind" data-kind='drink'>Drink</div>
<div className="kind" data-kind='sweet'>Sweet</div>
<div className="kind" data-kind='lorem'>lorem</div>
<div className="kind" data-kind='ipsum'>ipsum</div>
<div className="kind" data-kind='ipsum' >food</div>
</div>
);
}
export default Kind;
在初始化引用后,将其分配给dom需要一些时间。JavaScript是一种同步语言,不会等待引用初始化,而会直接跳过到日志。
为了解决这个问题,我们需要像这样使用useEffect
import { useRef, useEffect} from 'react';
import './kind.css'
const Kind = ({prop}) => {
// defining the ref
const kindRef = useRef('')
// using 'useEffect' will help us to do what ever you want to your ref varaible,
// by waiting to letting the elements to mount:'mount means after the elements get inserted in the page' and then do what you want the ref
useEffect(()=>{
// print the ref to the console
console.log(kindRef)
})
return (
<div ref={kindRef} className="kind-container" >
<div className="kind" data-kind='drink'>Drink</div>
<div className="kind" data-kind='sweet'>Sweet</div>
<div className="kind" data-kind='lorem'>lorem</div>
<div className="kind" data-kind='ipsum'>ipsum</div>
<div className="kind" data-kind='ipsum' >food</div>
</div>
);
}
export default Kind;
useEffect
等待引用被分配给DOM元素,然后运行分配给它的函数。
useLayoutEffect
。此外,记录kindRef.current
可能更安全,因为控制台日志不是静态的。最后,在像useEffect这样的钩子中始终指定依赖项数组可能是一个好习惯。 - Sharcoux如果你在使用useCallback
(或另一个hook)中的ref
,请记得将ref
添加到依赖项中:
const doSomething = useCallback(() => {
ref.current?.doIt();
}, [ref]);
<div ref={this.test}>
你必须将 ref
属性分配给你的 DOM 元素。
在这种情况下,你必须将 ref 分配给 div 元素。