رد فعل.شبيبة 2-طريقة الارتباطات:مسار عميق من مستويين في فالويلينك

StackOverflow https://stackoverflow.com//questions/21057219

سؤال

ولايتي هي:

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

أنا أستخدم مساعدين ملزمة في اتجاهين ولا يمكنني تقديم سلسلة مفاتيح صالحة لـ linkState:

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

سيكون لطيفا إذا this.linkState قبلت بعض بناء جملة الاستعلام، مثل "0.type" لاسترداد "translateX" من بلدي على سبيل المثال.

هل هناك أي حلول?


كتبت ديبلينكستات ميكسين وهو بديل انخفاض في رد فعل.إضافات. لينكدستاتيميكسين.مثال الاستخدام:

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

linkState("0.x") هو أيضا بناء جملة مقبول.

هل كانت مفيدة؟

المحلول

تحرير:

أدركت أن المسار العميق ل LinkedState هو بارد جدا لذلك أحاول تنفيذه.
الرمز: https://gist.github.com/tungd/8367229
الاستخدام: http://jsfiddle.net/uHm6k/3/


كما ذكرت الوثيقة, 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)
    ...
}

هنا يعمل جسفيدل: http://jsfiddle.net/srbGL/

نصائح أخرى

يمكنك تنفيذ المزيج الخاص بك إذا كان المزيج الأساسي لا يرضيك.

انظر كيف يتم تنفيذ هذا المزيج:

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

حتى تتمكن من محاولة بسهولة لكتابة بنفسك linkState وظيفة على أساس ما سبق.

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

لاحظ أنني لم تستخدم ReactStateSetters.createStateKeySetter(this, key). https://github.com/facebook/react/blob/fc73bf0a0abf739a9a8e6b1a5197dab113e76f27/src/core/ReactStateSetters.js من خلال النظر في شفرة المصدر مرة أخرى يمكنك معرفة هذا الأسلوب لا تفعل الكثير إلا أنه يخلق وظيفة ولا تحسينات التخزين المؤقت قليلا:

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

لذلك يجب عليك بالتأكيد محاولة كتابة المزيج الخاص بك.يمكن أن يكون هذا مفيدا جدا إذا كان لديك في حالتك كائن معقد وتريد تعديله من خلال واجهة برمجة تطبيقات الكائن.

أفعل ذلك دون استخدام الملحق قيمة الارتباط.

هنا هو تجريبي: http://wingspan.github.io/wingspan-forms/examples/form-twins/

الصلصة السرية هي تحديد وظيفة واحدة فقط عند التغيير:

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')} />

إذا كان لديك الكثير (value, onChange) أزواج التي لديك لتمرير في كل مكان ، قد يكون من المنطقي لتحديد التجريد حول هذا مماثل ل ريكتلينك ، ولكن أنا شخصيا حصلت بعيدا جدا دون استخدام ريكتلينك.

أنا وزملائي في الآونة الأخيرة مفتوحة المصدر جناحيها-أشكال, ، مكتبة رد فعل تساعد في حالة متداخلة بعمق.نحن الاستفادة من هذا النهج بشكل كبير.يمكنك رؤية المزيد من الأمثلة التوضيحية مع الحالة المرتبطة على صفحة جيثب.

لقد كتبت مدونة حول هذا الموضوع: http://blog.sendsonar.com/2015/08/04/angular-like-deep-path-data-bindings-in-react/

ولكن في الأساس أنا خلقت عنصر جديد من شأنه أن يقبل 'الدولة' من الأم ومسار عميق ، لذلك لم يكن لديك لكتابة رمز إضافي.

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

هناك جسفيدل جدا حتى تتمكن من اللعب معها

إليك البرنامج التعليمي الذي يشرح كيفية التعامل مع أشياء مثل هذه.

الدولة والأشكال في رد الفعل ، الجزء 3:التعامل مع الحالة المعقدة

ليرة تركية ؛ دكتور:

0) لا تستخدم الروابط القياسية.استخدام هذه.

1) تغيير دولتكم لتبدو مثل هذا:

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

2) خذ رابط إلى collection:

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

3) كرر من خلال الروابط إلى عناصرها:

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

أخذت نهجا مختلفا التي لا تستخدم ميكسينز ولا تتحول تلقائيا الدولة

انظر github.com/mcmlxxxviii/react-value-link

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top