Pergunta

O meu estado é:

[
  {type: "translateX", x: 10},
  {type: "scaleX", x: 1.2}
]

Eu estou usando A Vinculação De Duas Vias Auxiliares e eu não posso fornecer uma chave válida de seqüência de caracteres para linkState:

this.state.map(function(item, i) {
  return <div><input valueLink={this.linkState( ??? )}></div>
}

Seria bom se this.linkState aceitou algumas sintaxe de consulta, tais como "0.type" para recuperar "translateX" a partir do meu exemplo.

Existem soluções?


Eu escrevi DeepLinkState mixin o que é uma queda-de reposição para Reagir.addons.LinkedStateMixin.Exemplo de utilização:

this.state.map(function(item, i) {
  return <div><input valueLink={this.linkState([i, "x"])}></div>
}

linkState("0.x") também é aceitável sintaxe.

Foi útil?

Solução

Editar:

Eu percebi que a profunda o caminho para LinkedState é muito legal, assim que eu tentar implementá-lo.
Código: https://gist.github.com/tungd/8367229
Uso: http://jsfiddle.net/uHm6k/3/


Como o documento mencionado, LinkedState é um wrapper em torno de onChange/setState e significou para o caso simples.Você sempre pode escrever completo onChange/setState para conseguir o que você quer.Se você realmente quiser ficar com LinkedState, você pode usar o não mixin versão, por exemplo:

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)
    ...
}

Aqui é trabalho JSFiddle: http://jsfiddle.net/srbGL/

Outras dicas

Você pode implementar seu próprio mixin se a base mixin não satisfazê-lo.

Veja como este mixin é implementada:

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;
}

https://github.com/facebook/react/blob/fc73bf0a0abf739a9a8e6b1a5197dab113e76f27/src/addons/link/LinkedStateMixin.js https://github.com/facebook/react/blob/fc73bf0a0abf739a9a8e6b1a5197dab113e76f27/src/addons/link/ReactLink.js

Assim, você pode facilmente tentar escrever o seu próprio linkState função com base no acima exposto.

linkState: function(key,key2) {
  return new ReactLink(
    this.state[key][key2],
    function(newValue) {
      this.state[key][key2] = newValue;
    }
  );
}

Repare que eu não uso o ReactStateSetters.createStateKeySetter(this, key). https://github.com/facebook/react/blob/fc73bf0a0abf739a9a8e6b1a5197dab113e76f27/src/core/ReactStateSetters.js Olhando o código fonte, novamente, você pode encontrar este método não fazer muito, exceto que ele cria uma função e pouco faz cache de otimizações:

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);
  };
}

Então você deve definitivamente tentar escrever a sua própria mixin.Isso pode ser muito útil se você tiver em seu estado de um objeto complexo e você deseja modificá-lo através da API de objeto.

Eu fazê-lo sem utilizar o valor de vínculo addon.

Aqui está uma demonstração: http://wingspan.github.io/wingspan-forms/examples/form-twins/

O segredo do molho é só definir um onChange função:

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

usá-lo assim:

<input 
    value={this.state['forms']['0']['firstName']} 
    onChange={_.partial(this.onChange, 'forms', '0', 'firstName')} />

Se você tem muitos (value, onChange) pares que você tem que passar por todo o lugar, pode fazer sentido para definir uma abstração em torno deste semelhante ao ReactLink, mas eu, pessoalmente, tenho muito longe sem o uso de ReactLink.

Meus colegas e eu, recentemente, de código aberto envergadura-formulários, um Reagir biblioteca que ajuda-o com o profundamente aninhadas estado.Utilizamos esta abordagem fortemente.Você pode ver mais um exemplo de demos com vinculada estado na página do github.

Eu escrevi uma postagem no blog sobre isso: http://blog.sendsonar.com/2015/08/04/angular-like-deep-path-data-bindings-in-react/

Mas, basicamente, eu criei um novo componente que iria aceitar o 'estado' do pai, da mãe e de um profundo caminho, então você não precisa escrever um código extra.

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

Há um JSFiddle também, então você pode jogar com ele

Aqui está o tutorial explicando como lidar com coisas como esta.

Estado e Formas de Reagir, Parte 3:Tratamento o Complexo Estado

TL;DR:

0) não utilizar o padrão de links.Utilização estes.

1) Altere o seu estado para olhar como este:

collection : [
  {type: "translateX", x: 10},
  {type: "scaleX", x: 1.2}
]

2) Pegue o link para o collection:

var collectionLink = Link.state( this, 'collection' );

3) Iterar através de links para seus elementos:

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

Eu levei uma abordagem diferente, que não emprega mixins e não automaticamente mutar o estado

Ver github.com/mcmlxxxviii/react-value-link

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top