After reading forwarding refs from react legacy docs and following the examples from the SO post on using ref forwarding on classes, I tried to create a working example as following:
class Card extends React.Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
//after three seconds focus myRef
setTimeout(() => {
console.log(this.myRef);
this.myRef.current.focus();
}, 3000);
}
render() {
return <FancybtnWthRef ref={this.myRef} txt="random"/>;
}
}
//Fancybtn class based componenet with ref forwarding
class Fancybtn extends React.Component {
constructor(props) {
super(props);
const { innerRef, ...props2 } = this.props;
console.log(innerRef, this.props.innerRef); //doesn't get live binding to this.props.innerRef
}
render() {
return (
<button className="fancy-btn" ref={this.innerRef} {...this.props2}>
{this.props.txt}
</button>
);
}
}
const FancybtnWthRef = React.forwardRef((props, ref) => {
return <Fancybtn {...props} innerRef={ref} />;
});
ReactDOM.render(
<Card />,
document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
On the other hand, if I grab the this.props.innerRef
object directly for button, then it works:
class Card extends React.Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
//after three seconds focus myRef
setTimeout(() => {
console.log(this.myRef);
this.myRef.current.focus();
}, 3000);
}
render() {
return <FancybtnWthRef ref={this.myRef} txt="random"/>;
}
}
//Fancybtn class based componenet with ref forwarding
class Fancybtn extends React.Component {
constructor(props) {
super(props);
const { innerRef, ...props2 } = this.props;
console.log(innerRef, this.props.innerRef);
}
render() {
return (
<button className="fancy-btn" ref={this.props.innerRef} {...this.props2}>
{this.props.txt}
</button>
);
}
}
const FancybtnWthRef = React.forwardRef((props, ref) => {
return <Fancybtn {...props} innerRef={ref} />;
});
ReactDOM.render(
<Card />,
document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
In plain javascript destructuring gets live binding of objects as following:
var obj = {x:1, obj2: {y: 33}}
const {x, obj2} = obj;
obj2.y = 44;
cconsole.log(obj.obj2.y); //gives 44
Using the same argument why doesn't const { innerRef, ...props } = this.props;
grab the actual this.props.innerRef
for the button
?