I have a ReactJS component with an HTML <textarea>
inside.
The <textarea>
has the value
attribute pre-populated (see below ... I'm generating a link for the user to copy).
I want to automatically select the <textarea>
content so it'll be more convenient for the user to copy the text. I'm trying to do this in the React componentDidMount
call. It works... sort of.
As near as I can tell, the component is mounting so slowly that the process is still ongoing even when componentDidMount
is already being called. The reason I say this is: if I call myTextarea.select()
directly within componentDidMount
, it fails 100% of the time. However, if I put .select()
in a setTimeout(...)
call so it waits a bit before trying to select the content, it works 100% of the time.
Edit/note: after poking around a little more, I've discovered some sentiment indicating that using setTimeout(...)
for this purpose is poor practice, so now I'm even more eager to avoid using it.
What might I be missing, and is there a better way to accomplish this?
Here's what I have.
This version fails.
var GenerateLinkUi = React.createClass({
componentDidMount: function() {
document.getElementById('cyoag-generated-link-textarea').select();
},
render: function () {
return (
<div id='cyoag-generate-link-ui'>
<textarea readOnly id='cyoag-generated-link-textarea' value={config.hostDomain + 'link?id=' + this.props.nodeUid} />
</div>
);
}
});
This version succeeds.
var GenerateLinkUi = React.createClass({
componentDidMount: function() {
setTimeout(function(){
document.getElementById('cyoag-generated-link-textarea').select();
}, 500);
},
render: function () {
return (
<div id='cyoag-generate-link-ui'>
<textarea readOnly id='cyoag-generated-link-textarea' value={config.hostDomain + 'link?id=' + this.props.nodeUid} />
</div>
);
}
});
Edit: this was flagged as a duplicate. The linked question raises more questions for me, and does not provide a clear answer, as discussed in comments below. If ref
executes after the component mounts, and componentDidMount
also executes "after" component mounting, I struggle to understand the difference between the two, beyond the fact that ref
is passed a DOM element as an arg; where in componentDidMount
I'd have to use document.getElementById
or something. I'd appreciate if anyone could describe deeper differences between the two.
In the meantime I've found other workarounds for this issue but I'm still eager to learn more on the subject.