使用 React.createRef 时 current 始终为 null
current is always null when using React.createRef
我正在尝试 this。
我一定是漏掉了什么,但我不明白为什么在这个例子中 current
总是 null
。
class App extends React.PureComponent {
constructor(props) {
super(props);
this.test = React.createRef();
}
render() {
return <div className="App">current value : {this.test.current + ""}</div>;
}
}
你可以查看我的测试用例here
您缺少 ref={this.test}
道具。
return (
<div className="App" ref={this.test}>
current value : {this.test.current + ""}
</div>
);
因为您忘记将 ref 分配给某些 dom 元素。你只是在创造它。
这样写:
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>
)
}
}
React.createRef() 是异步的,因此如果您尝试访问 componentDidMount 中的 ref,它将 return 为 null,之后 return 您正在引用的组件的属性.
componentDidMount(): void {
if (this.viewShot && this.viewShot.current) {
this.viewShot.current.capture().then((uri) => {
console.log('do something with ', uri);
});
}
}
这是在此上下文中使用 React.createRef() 的正确方法。
我知道这不是 OP 问题的解决方案,但对于那些来自 google 搜索的人来说,ref.current 可以为 null 的一种方式是,如果正在附加的 ref 是一个连接的组件。就像 react-redux connect 或 withRouter 一样。对于 react-redux 解决方案是在第四个选项中传递 forwardRef:true 以连接。
<div ref={this.test}>
您必须将 ref
道具分配给您的 DOM 元素。
在这种情况下,您必须将 ref 分配给 div element
在以下情况下可能会发生这种情况:
- 您忘记将 ref 传递给组件,即问题中的
this.test
。
<Component ref={this.test} />
- 您正在使用 Redux,其中传递 ref 道具的组件由
connect
方法包装,因此this.test.current
会 return null 因为它指向 Redux 包装器,使这种组件工作 make forwardRef: true
i.e: connect(mapStateToProps, mapDispatchToProps, null, {forwardRef: true})(Component)
- 如果您同时使用
withRouter
和 connect
,那么在这里您将使用 两个 而不是 一个 wrappers 和 this.test.current
显然会 return null,为了克服这个问题确保 withRouter
包装 connect
withRouter(connect(mapStateToProps, mapDispatchToProps, null, {forwardRef: true})(Component))
然后
<Component wrappedComponentRef={ref => this.test = ref} />
wrappedComponentRef
是一个 prop,用于使包装组件像 forwardRef: true
一样可用,您可以在文档 here
中找到它
在 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;
初始化 ref 后,需要一些时间才能将其分配给 dom。 Javascript,作为一种同步语言,不等待 ref 初始化并直接跳到日志。
要解决这个问题,我们需要像这样使用 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
等待将 ref 分配给 DOM 元素,然后运行分配给它的函数。
如果你在useCallback
(或其他钩子)中使用ref
,请记住将ref
添加到依赖项中:
const doSomething = useCallback(() => {
ref.current?.doIt();
}, [ref]);
我正在尝试 this。
我一定是漏掉了什么,但我不明白为什么在这个例子中 current
总是 null
。
class App extends React.PureComponent {
constructor(props) {
super(props);
this.test = React.createRef();
}
render() {
return <div className="App">current value : {this.test.current + ""}</div>;
}
}
你可以查看我的测试用例here
您缺少 ref={this.test}
道具。
return (
<div className="App" ref={this.test}>
current value : {this.test.current + ""}
</div>
);
因为您忘记将 ref 分配给某些 dom 元素。你只是在创造它。
这样写:
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>
)
}
}
React.createRef() 是异步的,因此如果您尝试访问 componentDidMount 中的 ref,它将 return 为 null,之后 return 您正在引用的组件的属性.
componentDidMount(): void {
if (this.viewShot && this.viewShot.current) {
this.viewShot.current.capture().then((uri) => {
console.log('do something with ', uri);
});
}
}
这是在此上下文中使用 React.createRef() 的正确方法。
我知道这不是 OP 问题的解决方案,但对于那些来自 google 搜索的人来说,ref.current 可以为 null 的一种方式是,如果正在附加的 ref 是一个连接的组件。就像 react-redux connect 或 withRouter 一样。对于 react-redux 解决方案是在第四个选项中传递 forwardRef:true 以连接。
<div ref={this.test}>
您必须将 ref
道具分配给您的 DOM 元素。
在这种情况下,您必须将 ref 分配给 div element
在以下情况下可能会发生这种情况:
- 您忘记将 ref 传递给组件,即问题中的
this.test
。
<Component ref={this.test} />
- 您正在使用 Redux,其中传递 ref 道具的组件由
connect
方法包装,因此this.test.current
会 return null 因为它指向 Redux 包装器,使这种组件工作 makeforwardRef: true
i.e:
connect(mapStateToProps, mapDispatchToProps, null, {forwardRef: true})(Component)
- 如果您同时使用
withRouter
和connect
,那么在这里您将使用 两个 而不是 一个 wrappers 和this.test.current
显然会 return null,为了克服这个问题确保withRouter
包装connect
withRouter(connect(mapStateToProps, mapDispatchToProps, null, {forwardRef: true})(Component))
然后
<Component wrappedComponentRef={ref => this.test = ref} />
wrappedComponentRef
是一个 prop,用于使包装组件像 forwardRef: true
一样可用,您可以在文档 here
在 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;
初始化 ref 后,需要一些时间才能将其分配给 dom。 Javascript,作为一种同步语言,不等待 ref 初始化并直接跳到日志。
要解决这个问题,我们需要像这样使用 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
等待将 ref 分配给 DOM 元素,然后运行分配给它的函数。
如果你在useCallback
(或其他钩子)中使用ref
,请记住将ref
添加到依赖项中:
const doSomething = useCallback(() => {
ref.current?.doIt();
}, [ref]);