Custom ReactJS component that respects 'valueLink' Custom ReactJS component that respects 'valueLink' reactjs reactjs

Custom ReactJS component that respects 'valueLink'


The object returned from this.linkState when using the LinkedStateMixin has two relevant properties: value and requestChange(). Simply use those two properties as your value and change handler, respectively, just as if they had been passed to your custom component via value and onChange.

Here's an example of a composite component that wraps a jQuery color picker; it works both with valueLink and with standard value and onChange properties. (To run the example, expand the "Show code snippet" then click "" at the bottom.)

var ColorPicker = React.createClass({  render: function() {    return <div />;  },  getValueLink: function(props) {    // Create an object that works just like the one    // returned from `this.linkState` if we weren't passed    // one; that way, we can always behave as if we're using    // `valueLink`, even if we're using plain `value` and `onChange`.    return props.valueLink || {      value: props.value,      requestChange: props.onChange    };  },  componentDidMount: function() {    var valueLink = this.getValueLink(this.props);    jQuery(this.getDOMNode()).colorPicker({      pickerDefault: valueLink.value,      onColorChange: this.onColorChange    });  },  componentWillReceiveProps: function(nextProps) {    var valueLink = this.getValueLink(nextProps);    var node = jQuery(this.getDOMNode());    node.val(valueLink.value);    node.change();  },  onColorChange: function(id, color) {    this.getValueLink(this.props).requestChange(color);  }});

div.colorPicker-picker {  height: 16px;  width: 16px;  padding: 0 !important;  border: 1px solid #ccc;  background: url(https://raw.github.com/laktek/really-simple-color-picker/master/arrow.gif) no-repeat top right;  cursor: pointer;  line-height: 16px;}div.colorPicker-palette {  width: 110px;  position: absolute;  border: 1px solid #598FEF;  background-color: #EFEFEF;  padding: 2px;  z-index: 9999;}  div.colorPicker_hexWrap {width: 100%; float:left }  div.colorPicker_hexWrap label {font-size: 95%; color: #2F2F2F; margin: 5px 2px; width: 25%}  div.colorPicker_hexWrap input {margin: 5px 2px; padding: 0; font-size: 95%; border: 1px solid #000; width: 65%; }div.colorPicker-swatch {  height: 12px;  width: 12px;  border: 1px solid #000;  margin: 2px;  float: left;  cursor: pointer;  line-height: 12px;}
<script src="http://fb.me/react-with-addons-0.11.2.js"></script><script src="http://fb.me/JSXTransformer-0.11.2.js"></script><script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script><script src="https://dl.dropboxusercontent.com/u/113308/dnd/jsfiddle/jquery.colorPicker.min.js"></script><p><strong>With valueLink</strong></p><div id="app1"></div><hr><p><strong>With value and onChange</strong></p><div id="app2"></div><script type="text/jsx">/** @jsx React.DOM */var ApplicationWithValueLink = React.createClass({  mixins: [React.addons.LinkedStateMixin],  getInitialState: function() {    return { color: "#FF0000" }  },    render: function() {    return (      <div>        <div>          <span style={{color: this.state.color}}>My Color Picker</span>          <button onClick={this.changeColor.bind(null, "#FF0000")}>Red</button>          <button onClick={this.changeColor.bind(null, "#00FF00")}>Green</button>          <button onClick={this.changeColor.bind(null, "#0000FF")}>Blue</button>          <input type="text" valueLink={this.linkState("color")} />        </div>        <div>          <ColorPicker valueLink={this.linkState("color")} />        </div>      </div>    );  },    changeColor: function(color) {    this.setState({color: color});  }});var ApplicationWithoutValueLink = React.createClass({  getInitialState: function() {    return { color: "#FF0000" }  },    render: function() {    return (      <div>        <div>          <span style={{color: this.state.color}}>My Color Picker</span>          <button onClick={this.changeColor.bind(null, "#FF0000")}>Red</button>          <button onClick={this.changeColor.bind(null, "#00FF00")}>Green</button>          <button onClick={this.changeColor.bind(null, "#0000FF")}>Blue</button>          <input type="text" value={this.state.color} onChange={this.changeColorText} />        </div>        <div>          <ColorPicker value={this.state.color} onChange={this.changeColor} />        </div>      </div>    );  },    changeColor: function(color) {    this.setState({color: color});  },    changeColorText: function(evt) {    this.changeColor(evt.target.value);  }});var ColorPicker = React.createClass({  render: function() {    return (      <div />    );  },    getValueLink: function(props) {    return props.valueLink || {      value: props.value,      requestChange: props.onChange    };  },    componentDidMount: function() {    var valueLink = this.getValueLink(this.props);    jQuery(this.getDOMNode()).colorPicker({      pickerDefault: valueLink.value,      onColorChange: this.onColorChange    });  },    componentWillReceiveProps: function(nextProps) {    var valueLink = this.getValueLink(nextProps);    var node = jQuery(this.getDOMNode());    node.val(valueLink.value);    node.change();  },    onColorChange: function(id, color) {    this.getValueLink(this.props).requestChange(color);  }});React.renderComponent(<ApplicationWithValueLink />, document.getElementById("app1"));React.renderComponent(<ApplicationWithoutValueLink />, document.getElementById("app2"));</script>