XD’s support for React is pretty amazing, but there are some limitations, issues, and gotchas of which you need to be aware. This thread will summarize issues with React that are known, and what kind of workarounds (if any) you can use.
Issue
Checkboxes do not trigger change
events. You can use a ref
instead to assign an event handler.
Workaround
return (
<label class="row">
<input type="checkbox"
ref={el && el.addEventListener("change", e => {
/*…*/
})}
/>
<span>Check me!</span>
</label>
);
Issue
It’s not possible to supply a value to a SELECT
control at this time and have it rendered as selected.
Workaround
return (
<select value={selectedValue}
ref={el && el.setAttribute("value", selectedValue} />
<option value="1">Hello!</option>
<option value="2">There!</option>
</select>
);
Starting with React 16.5, react and react-dom make use of schedule
. Schedule makes use of cancelAnimationFrame (which is not available). Even after polyfills, it doesn’t work. It looks like ultimately schedule is using setTimeout. Even with the suggested polyfills for setTimeout I can’t get it to work.
For now, stay with 16.4.2 and everything works great.
I worked around this differently so that the value was autoselected (and not just available in JavaScript) by creating a wrapper component.
Here’s what the component looks like:
const React = require('react');
const PropTypes = require('prop-types');
// This component exists because <select>s' default values don't work in XD.
class XdSelect extends React.Component {
constructor() {
super(...arguments);
this.selectRef = React.createRef();
}
componentDidMount() { this._selectOptionByValue(); }
componentDidUpdate() { this._selectOptionByValue(); }
_selectOptionByValue() {
const selectEl = this.selectRef.current;
const {options, value} = this.props;
selectEl.selectedIndex = options.findIndex(option => (
option.value === value
))
}
render() {
const {options, disabled, value, onChange} = this.props;
return (
<select ref={this.selectRef} value={value || ''} onChange={onChange} disabled={Boolean(disabled)}>
{options.map(({value, name}) => (
<option key={value} value={value}>{name}</option>
))}
</select>
);
}
}
XdSelect.propTypes = {
options: PropTypes.arrayOf(PropTypes.shape({
value: PropTypes.string.isRequired,
name: PropTypes.string.isRequired
})).isRequired,
value: PropTypes.string.isRequired,
onChange: PropTypes.func.isRequired,
disabled: PropTypes.bool,
};
module.exports = XdSelect;
Here’s how to use it:
const options = [
{
value: 'foo',
name: 'Hello, Foo'
},
{
value: 'world',
name: 'Hello, World'
}
];
return <XdSelect
options={options}
value='world'
onChange={myOnSelectChangeFn}
disabled={false} />
This worked well for my purposes. Feel free to modify it as needed!
This thread should be listed in the DOCs. I spent ages in trying to fix the select box issue, and did not figure out, why it did not work, until I came across this post.
If there are known issues, and there are, link this Thread…