Last active
August 3, 2016 01:27
-
-
Save Jessidhia/0ce87560e4b3c93cd77475fdcf94b610 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react' | |
import classNames from 'classnames' | |
// I am trying to write a React version of an internal library's component. | |
// They share the CSS and class names, so the internal library's jquery event handler will capture clicks, | |
// thus I have to use a ref and attach handlers directly to it. | |
class Test extends React.Component { | |
constructor (props) { | |
super(props) | |
this.state = { | |
on: props.initialOn | |
} | |
this.handler = this.handler.bind(this) | |
} | |
toggle () { | |
const { state: { on } } = this | |
// With neither react-hot-loader/babel or transform-es2015-classes: works | |
// With both react-hot-loader/babel and transform-es2015-classes: works | |
// With react-hot-loader/babel but not transform-es2015-classes: "Can only update a mounted or mounting component." | |
// Moving the "this.handler = this.handler.bind(this)" to componentDidMount makes it work on all cases | |
this.setState({ | |
on: !on | |
}) | |
} | |
handler (e) { | |
e.stopPropagation() // stop the other library's event handler | |
this.toggle() | |
} | |
componentDidMount () { | |
this.ref.addEventListener('click', this.handler) | |
} | |
componentWillUnmount () { | |
this.ref.removeEventListener('click', this.handler) | |
} | |
render () { | |
const { | |
props: { name, children }, | |
state: { on } | |
} = this | |
const classes = classNames('_ui-switch', { | |
'on': on, | |
'off': !on | |
}) | |
return ( | |
// to run before the other library, must add event directly to the DOM node instead of using onClick | |
<div className={classes} ref={(ref) => { this.ref = ref }}> | |
<span className='label'>{children}</span> | |
<span className='toggle-switch'> | |
<span className='switch'/> | |
</span> | |
{/* Warning about "changing an uncontrolled input" will be fixed in v15.2 */} | |
<input type='checkbox' name={name} checked={on} readOnly/> | |
</div> | |
) | |
} | |
} | |
Test.propTypes = { | |
initialOn: React.PropTypes.bool, | |
name: React.PropTypes.string.isRequired, | |
children: React.PropTypes.node.isRequired // contents of the label | |
} | |
import $ from 'jquery' | |
import ReactDOM from 'react-dom' | |
$(() => { | |
const el = $('<div></div>').prependTo(document.body).get(0) | |
ReactDOM.render(<Test name='switch' initialOn={true}>switch</Test>, el) | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment