Reputation: 11712
I'm building a React website with fluentui/react-nothstar package controls. Below you can find a simplified example of Text + Button. My scenario is to access the text control when the button is pressed. I need something like document.findElementById which works via refs in React. It works great for component controls (that extends React.Component) but fails for Northstar components with the error:
Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?
Based on the warning details and the Text control definition, it looks like it's a function component and I have to use React forwardRef to access its properties. I tried multiple ways to do this here, here, and here but wasn't successful.
import React from 'react';
import {
Text,
Button,
}
from '@fluentui/react-northstar';
class Welcome extends React.Component {
private textRef: any = React.createRef();
private doJob1() {
console.log("doJob1 executed");
console.log(this.textRef.current); // returns null
}
render() {
return (
<div>
<div>Welcome</div>
<div>
<Text
ref={this.textRef}
content="My fancy text control" />
<Button
onClick={this.doJob1.bind(this)}
content="My fancy button" />
</div>
</div>
);
}
}
export default Welcome;
In most cases, I can avoid direct element access by use props and state but in some cases, I still need a component reference (change focus, open dialog, update values not defined in my state).
What is the right way to access the Text control in the Button click handler in the example above?
Upvotes: 1
Views: 718
Reputation: 11712
Turned out that Ref was designed for that:
<Ref innerRef={this.textRef}>
<Text content="My fancy text control" />
</Ref>
Upvotes: 1
Reputation: 412
In that case, the library needs to forward the ref, which apparently they don't.
But in general, you want to use controlled components to capture user input like that. Basically, you need to set a variable to track the value in the parent component (Welcome, in your case), pass it down as the value
to the <Text />
component and capture the changes from its onChange
. Then, on the button's onClick
, the value will be up to date with whatever is the user input.
Upvotes: 1