Frage

Mein Zustand ist:

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

Ich benutze Zwei-Wege-Bindehelfer und ich kann keine gültige Schlüsselzeichenfolge für angeben linkState:

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

Wäre schön, wenn this.linkState akzeptierte einige Abfragesyntax, wie z "0.type" abrufen "translateX" aus meinem Beispiel.

Gibt es Problemumgehungen?


Ich schrieb DeepLinkState-Mixin welches ist ein Drop-In-Ersatz für React.in: addons.LinkedStateMixin.Anwendungsbeispiele:

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

linkState("0.x") ist auch akzeptable Syntax.

War es hilfreich?

Lösung

Bearbeiten:

Ich erkannte diesen tiefen Weg für LinkedState ist ziemlich cool, also versuche ich es umzusetzen.
Codes: https://gist.github.com/tungd/8367229
Nutzung: http://jsfiddle.net/uHm6k/3/


Wie im Dokument angegeben, LinkedState ist ein Wrapper herum onChange/setState und für den einfachen Fall gedacht.Sie können immer das Ganze schreiben onChange/setState um zu erreichen, was Sie wollen.Wenn du wirklich dabei bleiben willst LinkedState, können Sie zum Beispiel die Nicht-Mixin-Version verwenden:

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

Hier arbeitet JSFiddle: http://jsfiddle.net/srbGL/

Andere Tipps

Sie können Ihr eigenes Mixin implementieren, wenn das Basis-Mixin Sie nicht zufriedenstellt.

Sehen Sie, wie dieses Mixin implementiert ist:

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

So können Sie ganz einfach versuchen, Ihre eigenen zu schreiben linkState funktion basierend auf dem oben genannten.

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

Beachten Sie, dass ich das nicht benutzt habe ReactStateSetters.createStateKeySetter(this, key). https://github.com/facebook/react/blob/fc73bf0a0abf739a9a8e6b1a5197dab113e76f27/src/core/ReactStateSetters.js Wenn Sie sich den Quellcode noch einmal ansehen, können Sie feststellen, dass diese Methode nicht so viel bewirkt, außer dass sie eine Funktion erstellt und kleine Caching-Optimierungen vornimmt:

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

Sie sollten also auf jeden Fall versuchen, Ihr eigenes Mixin zu schreiben.Dies kann sehr nützlich sein, wenn Sie in Ihrem Status ein komplexes Objekt haben und es über die Objekt-API ändern möchten.

Ich mache es ohne Value-Link-Addon.

Hier ist eine Demo: http://wingspan.github.io/wingspan-forms/examples/form-twins/

Die geheime Sauce besteht darin, nur eine onChange-Funktion zu definieren:

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

benutze es so:

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

Wenn Sie viele haben (value, onChange) paare, die Sie überall herumreichen müssen, könnte es sinnvoll sein, eine Abstraktion ähnlich wie ReactLink zu definieren, aber ich persönlich bin ziemlich weit gekommen, ohne ReactLink zu verwenden.

Meine Kollegen und ich haben kürzlich Open Source spannweite-Formen, eine Reaktionsbibliothek, die bei tief verschachtelten Zuständen hilft.Wir nutzen diesen Ansatz stark.Weitere Beispieldemos mit verknüpftem Status finden Sie auf der Github-Seite.

Ich habe einen Blogpost darüber geschrieben: http://blog.sendsonar.com/2015/08/04/angular-like-deep-path-data-bindings-in-react/

Aber im Grunde habe ich eine neue Komponente erstellt, die den 'Status' des übergeordneten Elements und einen tiefen Pfad akzeptiert, sodass Sie keinen zusätzlichen Code schreiben müssen.

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

Es gibt auch eine JSFiddle, damit Sie damit spielen können

Hier ist das Tutorial, das erklärt, wie man mit solchen Dingen umgeht.

Zustand und Formen in React, Teil 3:Umgang mit dem komplexen Zustand

TL; DR:

0) Verwenden Sie keine Standardlinks.Verwenden diese.

1) Ändern Sie Ihren Status so, dass er so aussieht:

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

2) Nehmen Sie den Link zum collection:

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

3) Durchlaufen Sie die Links zu seinen Elementen:

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

Ich habe einen anderen Ansatz gewählt, der keine Mixins verwendet und den Zustand nicht automatisch mutiert

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

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top