Redux: سؤال: تحور كائن داخلي في حالة في مخفض

تم إنشاؤها على ١٥ أبريل ٢٠١٦  ·  3تعليقات  ·  مصدر: reduxjs/redux

هل هذا مخفض إعادة إحياء صالح؟

function reducer(state={ byId: {}, ids: [] }, action) {
  switch (action.type) {
    case 'ADD':
      state = { ...state }
      state.byId[action.id] = action.value
      state.ids.push(action.id)
      return state

    default:
      return state
  }
}

الحالة بأكملها مستنسخة ضحلة أولاً ، لذلك سيتم إرجاع كائن جديد ، لكن الكائنات الداخلية تظل كما هي وتتحول.

أو يجب أن أفعل شيئًا مثل:

function reducer(state={ byId: {}, ids: [] }, action) {
  switch (action.type) {
    case 'ADD':
      return {
        ...state,
        byId: {
          ...state.byId,
          [action.id]: action.value
        },
        ids: [ ...state.ids, action.id ]
      }

    default:
      return state
  }
}

الآثار الجانبية التي أراها مع الطريقة الأولى موجودة في DevTools LogMonitor:

  • سيؤدي توسيع عقدة فرعية (على سبيل المثال byId ) في حالة سابقة إلى إظهار نفس قيمة العقدة الأحدث حتى عندما كانت شيئًا آخر سابقًا
  • السفر عبر الزمن لا يعمل

هل هو مجرد خطأ في LogMonitor أم أن الطريقة الثانية هي الطريقة الصحيحة؟ إذا قمت بإضافة state = _.cloneDeep(state) قبل الطفرات ، فإنه يعمل بشكل جيد بالفعل ، مما يثبت أن LogMonitor يعيد استخدام نفس الكائنات ، وبالتالي القيم نفسها.

يعمل باقي التطبيق بشكل جيد ومع ذلك يتم تحديث المشاهدات بشكل صحيح على @connect ed.

التعليق الأكثر فائدة

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

أيضا تكوين المخفض يساعد في ذلك.

function byId(state = {}, action) {
  switch (action.type) {
    case 'ADD':
      return {
        ...state,
        [action.id]: action.value
      }
    default:
      return state
  }
}

function ids(state = [], action) {
  switch (action.type) {
    case 'ADD':
      return [ ...state, action.id ]
    default:
      return state
  }
}

const reducer = combineReducers({
  byId,
  ids
})

ال 3 كومينتر

كلا ، هذا المثال الأول يغير الحالة تمامًا. تنشئ النسخة الأولية السطحية كائنًا جديدًا ، لكن الكائن الجديد يشير إلى المراجع byId و ids مثل الأصل. لذلك ، عندما تفعل byId[action.id] = action.value و ids.push(action.id) ، فإنك تغير العناصر الأصلية.

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

تحتوي الأسئلة الشائعة حول Redux أيضًا على سؤال يغطي التحديث الصحيح للحالة بشكل ثابت: http://redux.js.org/docs/FAQ.html#react -not-rerendering.

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

أيضا تكوين المخفض يساعد في ذلك.

function byId(state = {}, action) {
  switch (action.type) {
    case 'ADD':
      return {
        ...state,
        [action.id]: action.value
      }
    default:
      return state
  }
}

function ids(state = [], action) {
  switch (action.type) {
    case 'ADD':
      return [ ...state, action.id ]
    default:
      return state
  }
}

const reducer = combineReducers({
  byId,
  ids
})

تضمين التغريدة انتهى بي الأمر بكتابة مخفض عالي الترتيب يدير القوائم الديناميكية المفهرسة (حسب المعرف)

الكود: https://gist.github.com/elado/95484b754f31fcd6846c7e75de4aafe4

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات