Javascript React.js双向绑定:valueLink中的两级深度路径

Javascript React.js双向绑定:valueLink中的两级深度路径,javascript,data-binding,reactjs,Javascript,Data Binding,Reactjs,我的国家是: [ {type: "translateX", x: 10}, {type: "scaleX", x: 1.2} ] 我正在使用,无法为linkState提供有效的密钥字符串: this.state.map(function(item, i) { return <div><input valueLink={this.linkState( ??? )}></div> } linkState(“0.x”)也是可以接受的语法。编辑: 我意

我的国家是:

[
  {type: "translateX", x: 10},
  {type: "scaleX", x: 1.2}
]
我正在使用,无法为
linkState
提供有效的密钥字符串:

this.state.map(function(item, i) {
  return <div><input valueLink={this.linkState( ??? )}></div>
}
linkState(“0.x”)
也是可以接受的语法。

编辑:

我意识到
LinkedState的深层路径非常酷,所以我尝试实现它。
代码:
用法:


正如文档所述,
LinkedState
是一个围绕
onChange/setState
的包装器,用于简单的情况。您可以随时编写完整的
onChange/setState
,以实现所需的功能。如果您确实想继续使用
LinkedState
,可以使用非混入版本,例如:

getInitialState: function() {
    return { values: [
        { type: "translateX", x: 10 },
        { type: "scaleX", x: 1.2 }
    ]}
},
handleTypeChange: function(i, value) {
    this.state.values[i].type = value
    this.setState({ values: this.state.values })
},
render: function() {
    ...
    this.state.values.map(function(item, i) {
        var typeLink = {
            value: this.state.values[i].type,
            requestChange: this.handleTypeChange.bind(null, i)
        }
        return <div><input valueLink={typeLink}/></div>
    }, this)
    ...
}
getInitialState:function(){
返回{个值:[
{type:“translateX”,x:10},
{type:“scaleX”,x:1.2}
]}
},
handleTypeChange:函数(i,值){
this.state.values[i].type=value
this.setState({values:this.state.values})
},
render:function(){
...
this.state.values.map(函数(项,i){
变量类型链接={
value:this.state.values[i].type,
requestChange:this.handleTypeChange.bind(null,i)
}
返回
},本页)
...
}

下面是正在工作的JSFiddle:

如果基本mixin不能满足您的要求,您可以实现自己的mixin

查看如何实现此mixin:

var LinkedStateMixin = {
  /**
   * Create a ReactLink that's linked to part of this component's state. The
   * ReactLink will have the current value of this.state[key] and will call
   * setState() when a change is requested.
   *
   * @param {string} key state key to update. Note: you may want to use keyOf()
   * if you're using Google Closure Compiler advanced mode.
   * @return {ReactLink} ReactLink instance linking to the state.
   */
  linkState: function(key) {
    return new ReactLink(
      this.state[key],
      ReactStateSetters.createStateKeySetter(this, key)
    );
  }
};

/**
 * @param {*} value current value of the link
 * @param {function} requestChange callback to request a change
 */
function ReactLink(value, requestChange) {
  this.value = value;
  this.requestChange = requestChange;
}

因此,您可以基于上述内容轻松编写自己的
linkState
函数

linkState: function(key,key2) {
  return new ReactLink(
    this.state[key][key2],
    function(newValue) {
      this.state[key][key2] = newValue;
    }
  );
}
请注意,我没有使用
ReactStateSetters.createStateKeySetter(这个,键)
。 通过再次查看源代码,您可以发现此方法除了创建一个函数和很少进行缓存优化之外,没有做太多的工作:

function createStateKeySetter(component, key) {
  // Partial state is allocated outside of the function closure so it can be
  // reused with every call, avoiding memory allocation when this function
  // is called.
  var partialState = {};
  return function stateKeySetter(value) {
    partialState[key] = value;
    component.setState(partialState);
  };
}
所以你一定要试着写你自己的混音。
如果您的状态中有一个复杂的对象,并且希望通过对象API对其进行修改,那么这将非常有用。

我不使用value link插件就可以完成此操作

下面是一个演示:

秘诀是只定义一个onChange函数:

onChange: function (path, /* more paths,*/ value) {
    // clone the prior state
    // traverse the tree by the paths and assign the value
    this.setState(nextState);
}
像这样使用它:

<input 
    value={this.state['forms']['0']['firstName']} 
    onChange={_.partial(this.onChange, 'forms', '0', 'firstName')} />
collection : [
  {type: "translateX", x: 10},
  {type: "scaleX", x: 1.2}
]

如果您有许多必须到处传递的
(value,onChange)
对,那么围绕这一点定义一个类似于ReactLink的抽象可能是有意义的,但我个人在没有使用ReactLink的情况下取得了相当大的进步


我和我的同事最近开源了一个React库,它有助于处理深度嵌套的状态。我们在很大程度上利用了这种方法。您可以在github页面上看到更多带有链接状态的示例演示。

我写了一篇关于它的博客:

但基本上我创建了一个新组件,它将接受父级的“状态”和一个深层路径,因此您不必编写额外的代码

<MagicInput binding={[this, 'account.owner.email']} />


还有一个JSFiddle,因此您可以使用它

我采用了一种不同的方法,它不使用mixin,也不会自动改变状态


请参见

这是解释如何处理此类问题的教程

TL;博士:

0)不要使用标准链接。使用

1) 将您的状态更改为如下所示:

<input 
    value={this.state['forms']['0']['firstName']} 
    onChange={_.partial(this.onChange, 'forms', '0', 'firstName')} />
collection : [
  {type: "translateX", x: 10},
  {type: "scaleX", x: 1.2}
]
2) 获取指向
集合的链接

var collectionLink = Link.state( this, 'collection' );
3) 遍历指向其元素的链接:

collectionLink.map(function( itemLink, i ) {
  return <div><input valueLink={itemLink}></div>
})
collectionLink.map(函数(itemLink,i){
返回
})

非常感谢您的Mixin(catalyst repo),@tungd。欢迎来到Stack Overflow!虽然这可以回答问题,但请在此处包含答案的基本部分,并提供链接以供参考。