Search code examples
javascriptreactjsreact-domcxjs

Cx framework: How to access a DOM element in Cx?


I am exploring Cx, an interesting new framework based on React (http://cx.codaxy.com/) and I can't figure out how to access a DOM element inside a component.

Basically, I have a simple widget that contains some text and a button, and on button click I want to have that text copied to the clipboard, and because of browsers' security restrictions, this has to be done by selecting the text inside an input field and executing document.execCommand('copy'); In React, I would use ref and it would look something like this:

class MyWidget extends React.Component {    
    copyToClipboard = () => {
        // copy text from this.textInput to clipboard...
        // select text
        this.textInput.select();
        try {
            // copy selected text
            document.execCommand('copy');
            this.textInput.blur(); // deselect text
        } catch (err) {
            alert('Please press CTRL/CMD+C to copy');
        }
    }
    render(){
        return (
            <div>
                <span className="inputWithButton">
                <input 
                    ref={(input) => this.textInput = input} 
                    type="text" value="some text..." 
                    onClick={this.copyToClipboard}
                />
                <button onClick={this.copyToClipboard} >
                    Copy to clipboard
                </button>
                </span>
            </div>
        );
    }
}

But Cx doesn't use refs in its' custom components. Is there any other way to achieve this?

Any help will be greatly appreciated.


Solution

  • When Cx widgets require DOM access it's usually handled in one of these two ways:

    1. Use event.target

    In the copyToClipboard callback method, the first argument is the event. event.target points to the DOM element being clicked. You could use event.target.previousSibling to get to the input, although that feels hacky and could break if you change your DOM structure.

    1. Use React component

    It's perfectly fine to return React components from Cx render method. So you may use what you already wrote, just wrap in the Cx widget.

    render(context, instance, key) {
      return <MyWidget key={key} ... />
    }