Question

Mon état est:

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

Je suis à l'aide d' La Liaison Bidirectionnelle Aides et je ne peux pas fournir une clé valide pour la chaîne linkState:

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

Ce serait bien si this.linkState accepté certains de la syntaxe de requête, tels que "0.type" pour récupérer "translateX" de mon exemple.

Existe-il des solutions?


J'ai écrit DeepLinkState mixin une baisse-dans le remplacement pour Réagir.addons.LinkedStateMixin.Exemple d'utilisation:

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

linkState("0.x") est également acceptable de la syntaxe.

Était-ce utile?

La solution

Edit:

J'ai réalisé qu'au plus profond de chemin pour LinkedState est assez cool donc j'essaie de la mettre en œuvre.
Le code: https://gist.github.com/tungd/8367229
Utilisation: http://jsfiddle.net/uHm6k/3/


Comme le document a dit, LinkedState est un wrapper autour de onChange/setState et signifiait pour les cas simple.Vous pouvez toujours écrire le plein onChange/setState pour atteindre ce que vous voulez.Si vous voulez vraiment le bâton avec LinkedState, vous pouvez utiliser le mixin version, par exemple:

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

Voici de travail JSFiddle: http://jsfiddle.net/srbGL/

Autres conseils

Vous pouvez implémenter votre propre mixin si la base mixin ne vous satisfait pas.

Voir comment ce mixin est mis en œuvre:

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

Donc, vous pouvez facilement essayer d'écrire votre propre linkState fonctionnement basé sur la ci-dessus.

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

Notez que je n'ai pas utiliser le ReactStateSetters.createStateKeySetter(this, key). https://github.com/facebook/react/blob/fc73bf0a0abf739a9a8e6b1a5197dab113e76f27/src/core/ReactStateSetters.js En regardant le code source de nouveau, vous pouvez trouver cette méthode ne prend pas en faire autant, sauf qu'il crée une fonction, et fait un peu de mise en cache des optimisations:

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

Donc, vous devriez certainement essayer d'écrire votre propre mixin.Cela peut être très utile si vous avez dans votre état d'un objet complexe et vous souhaitez le modifier par le biais de l'objet de l'API.

- Je le faire sans l'aide de la valeur de lien addon.

Voici une démo: http://wingspan.github.io/wingspan-forms/examples/form-twins/

Le secret de la sauce est à seulement définir un onChange de la fonction:

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

l'utiliser comme ceci:

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

Si vous avez de nombreux (value, onChange) paires que vous avez à passer partout, il pourrait être judicieux de définir une abstraction autour de ce similaire à ReactLink, mais personnellement, je suis assez loin sans l'aide de ReactLink.

Mes collègues et j'ai récemment open source envergure-formes, une Réagir la bibliothèque qui aide à profondément imbriquée état.Nous tirons parti de cette approche fortement.Vous pouvez voir plus d'exemple démos lié avec l'état sur la page github.

J'ai écrit un billet de blog à ce sujet: http://blog.sendsonar.com/2015/08/04/angular-like-deep-path-data-bindings-in-react/

Mais fondamentalement, j'ai créé un nouveau composant qui accepterait l'état de parent et d'un profond chemin, de sorte que vous n'avez pas à écrire du code supplémentaire.

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

Il y a un JSFiddle trop de sorte que vous pouvez jouer avec elle

Voici le tutoriel expliquant comment gérer les choses comme cela.

De l'état et Formes de Réagir, Partie 3:La manipulation de la complexité de la situation

TL;DR:

0) Ne pas utiliser de liens classiques.Utilisation ces.

1) Changement de votre état de ressembler à ceci:

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

2) Prendre le lien de la collection:

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

3) Itérer sur les liens pour l'un de ses éléments:

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

J'ai pris une approche différente, qui n'emploie pas de mixin et ne met pas automatiquement à la mutation de l'état

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top