ReactJS:如何获得组件的所有者



ReactJS鼓励单向数据流,但我想打破它以便于开发,我需要双向绑定输入框。

我想要这样的组件

var App = React.createClass({
    getInitialState: function(){
        return {
            user: {
                name: ''
            }
        }
    },
    render: function(){
        return <TwoWayBinder type="input" model="user.name" />;
    }
});

其中user.namethis.state 中的变量。所以,我希望<TwoWayBinder />组件访问其父组件的状态(根据 React 哲学,这是一种反模式)。我看到父组件在 TwoWayBinder 组件_owner属性中可用。

这是接近所有者的唯一方法吗?出于多种原因,我不想使用valueLink

没有用于访问所有者的文档 API。 _owner是唯一没有记录的方式(据我所知)。

更新:"component._owner在 0.13 中不再可用" -zbyte


我个人不是valueLink的粉丝。 我一直在研究一个类似但更强大的系统。

在最低级别形式中,您的代码如下所示: jsbin 1

var App = React.createClass({
  mixins: [formMixin],
  getInitialState: function(){
    return {
      data: { name: "", email: "" }
    }
  },
  render: function(){
    var formData = this.stateKey("data");
    return (
      <div>
        <input type="text" value={this.state.data.name} onChange={formData.forKey("name").handler()} />
        <input type="text" value={this.state.data.email} onChange={formData.forKey("email").handler() } />
      </div>
    );
  }
});

这还不错,并且给了你很多控制权,但你可能想要更快的东西。 JSBin 2

var Input = React.createClass({
  render: function(){
    var link = this.props.link;
    return <input type="text" 
                  {...this.props} 
                  value={link.getCurrentValue()} 
                  onChange={link.handler()} />
  }
});
var App = React.createClass({
  mixins: [formMixin],
  getInitialState: function(){
      return { data: { name: "", email: "" } }
    }
  },
  render: function(){
    var formData = this.stateKey("data");
    return (
      <div>
        <Input link={formData.forKey("name")} />
        <Input link={formData.forKey("email")} />
      </div>
    );
  }
});

为了完整起见,以下是完整的混合:

var formMixinHandler=function(thisArg,keys,parent){return{forKey:function(key){return formMixinHandler(thisArg,keys.concat(key),this)},bindTo:function(newThisArg){return formMixinHandler(newThisArg,keys,this)},transform:function(fn){var obj=formMixinHandler(thisArg,keys,this);obj.transforms=obj.transforms.concat(fn);return obj},transforms:parent?parent.transforms:[],handler:function(){var self=this;return function(event){var value=event;if(event.target instanceof HTMLInputElement)if(event.target.type==="checkbox"||event.target.type==="radio")value=event.target.checked;else value=event.target.value;self.transforms.reduce(function(last,fn){return fn(last,event)},value);var targetObj=keys.slice(0,-1).reduce(function(obj,key){if(!obj[key])obj[key]={};return obj[key]},thisArg.state);targetObj[keys[keys.length-1]]=value;var updateObject={};updateObject[keys[0]]=thisArg.state[keys[0]];thisArg.setState(updateObject)}},getCurrentValue:function(){return keys.reduce(function(obj,key){return obj?obj[key]:null},thisArg.state)}}};var formMixin={stateKey:function(key){return formMixinHandler(this,[].concat(key))}};

只是为了解决这个问题,确实有内部 API 可以在 0.13 版本中获取所有者:

this._reactInternalInstance._currentElement._owner._instance

如您所知,真的不推荐这样做。

最新更新