reactjs - examples - react js ماهو



كيفية تجنب "الأطفال مع نفس المفتاح" عند استبدال الدولة في مكون رياكتجس (2)

لقد أنشأت مكون رد فعل يجعل مجموعة من العناصر الفرعية نظرا لمجموعة من المعرفات. يتم الاحتفاظ مصفوفة من المعرفات في حالة المكون الأصل ثم قم بتشغيل بعض مكالمات أجاكس استنادا إلى إدس لجلب البيانات إلى تقديم. يتم تخزين البيانات التي تم جلبها في مصفوفة بيانات منفصلة في الولاية. تستخدم المكونات المقدمة المعرف كمفتاح .

يمكن أن تتغير المعرفات استنادا إلى إجراءات خارج المكون، لذلك يمكنني استخدام سيتستات على المكون لاستبدال الصفيف. قد تحتوي معرف الحالة المحدثة على بعض المعرفات نفسها كما في الصفيف الأصلي. وفي الوقت نفسه إفراغ "مجموعة البيانات" بحيث يتم تقديم كل شيء مرة أخرى.

عندما أفعل ذلك أحصل أحيانا على تحذير المفتاح:

تحذير: فلاتينشيلدرن (...): واجه طفلين مع نفس المفتاح. مفاتيح الطفل يجب أن تكون فريدة من نوعها. عندما يشارك طفلان مفتاح، سيتم استخدام الطفل الأول فقط.

لا يحتوي الصفيف الجديد على أية نسخ مكررة. فلماذا يحدث، وماذا يمكنني أن أفعل لتجنب ذلك؟

تعديل: تمت إضافة بعض الشفرة حسب الطلب. ملاحظة: أنا باستخدام وحدة التمرير اللانهائي . هل يمكن أن يسبب ذلك؟

الحالة الأولية:

getInitialState: function() {
  return {
    hasMore: true,
    num: 0,
    movieIds: this.props.movieIds,
    movies: []
  };
},

وظيفة التقديم:

render: function() {
  var InfiniteScroll = React.addons.InfiniteScroll;

  return (
    <InfiniteScroll
        pageStart={0}
        loadMore={this.loadMore}
        threshold='20'
        hasMore={this.state.hasMore}>
        <ul className="movieList">
          {this.state.movies}
        </ul>
    </InfiniteScroll>       
);
}

تحميل مبسط أكثر:

comp = this;
$.ajax( {
  url: url,
  contentType: "json",
  success: function (data) {
    var m = createMovieLi(data);
    var updatedMovies = comp.state.movies;
    updatedMovies[num] = m;
    comp.setState({movies: updatedMovies});
  }
});

وأخيرا عند تحديث خارج المكون:

movieBox.setState({
  hasMore: true,
  num: 0,
  movieIds: filteredIds,
  movies: []
});

https://ffff65535.com


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

بسبب إمكانية التكرارات أنا تخزين كل استجابة أجاكس في window.localStorage، على موفيديد. او كذلك ظننت انا.

في رد فعل إنفينيت انتقل كل عنصر في قائمتك يتم رسم بالتتابع مع استدعاء لودمور وظيفة. داخل هذه الوظيفة فعلت دعوة أجاكس بلدي، وتخزين النتيجة في ذاكرة التخزين المؤقت للمتصفح. بدا الرمز شيئا من هذا القبيل:

  var cachedValue = window.localStorage.getItem(String(movieId));
  var cachedData = cachedValue ? JSON.parse(cachedValue) : cachedValue;

  if (cachedData != null) {
    comp.drawNextMovie(cachedData);
  } else { 
    $.ajax( {
      type: "GET",
      url: this.state.movieUrl + movieId,
      contentType: "json",
      success: function (movieData) {
        window.localStorage.setItem(String(movieId), JSON.stringify(movieData));
        comp.drawNextMovie(movieData);
      }
    });  
  }    

يمكنك بقعة الخطأ؟ عندما يعود أجاكس المكالمة، موفيديد لم يعد ما كان. لذلك أنا في نهاية المطاف تخزين البيانات عن طريق معرف خاطئ، والحصول على بعض التحذيرات رد فعل غريب في المقابل. لأن هذا تم داخل وظيفة لودمور تسمى وحدة إنفينيتيسكرول، لم أكن على علم بأن هذه الوظيفة لم يتم تحديد النطاق بشكل صحيح.

أنا إصلاحه عن طريق إضافة تعبير وظيفة استدعاء فورا .


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

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

دون معرفة بالضبط كيفية عمل أرقام التعريف الخاصة بك فإنه من المستحيل أن أقول ما يسبب الصدام غير فريدة من نوعها هنا. ولكن بما أن key هو السماح فقط بالاستجابة لتحديد العناصر بشكل صحيح، وليس هناك أي شيء آخر، فإنه ليس من المنطقي حقا أن يكون أي شيء سوى عدد بسيط أو مؤشر.

var children = [];
for (var i=0; i<yourArray.length; i++) {
    children.push(
        <div key={i}>{yourArray[i].someProp}</div>
    );
}