Как мы можем предотвратить сбои мобильных приложений, если кэшированные данные не соответствуют новой структуре редукторов?

#react-native #caching #mobile-application #offline-caching #redux-persist

Вопрос:

В настоящее время я разрабатываю мобильное приложение для управления электронной коммерцией с помощью React Native и Redux. Мы сохраняем данные с помощью redux-persist. Это обеспечивает отличный опыт работы с кэшированными данными, что является принципом разработки в автономном режиме.

Но может быть ошибка, которая может произойти в среде мобильного мира.

Давайте предположим, что у меня есть редуктор под названием «продукты». Этот редуктор-это просто массив с объектами продукта. Пользователь входит в систему, и теперь данные в этом редукторе сохраняются. Позже моя команда разработчиков решает обновить мобильное приложение новой структурой на этом редукторе «продукты». Приложение пользователя обновляется, и теперь сохраненные/кэшированные данные не соответствуют новой структуре редуктора «продукты», что приводит к сбою приложения.

Возможно, я ошибаюсь, но действительно ли это ошибка, которая может существовать? Если да, то что такое обходной путь или решение?

Спасибо!

Ответ №1:

Это потенциальная ошибка, которая может существовать, я согласен, потому что это случалось со мной дважды, и я обнаружил кое-что, что может вам помочь. Причина сбоя зависит от того, что хранится на диске и что использует ваш код, позвольте мне объяснить.

 //let say we have a reducer function ProductReducer(  state={  products:[],  fetching:false  },action){  switch(){......} }   // lets say we have a combine reducer combineReducers({  products: ProductReducer })  //let say we have a component that consums this products function RenderProducts(){ const {products, fetching} = useSelector((store)=gt;({  products: store.products.products,  fetching: store.products.fetching, })) return (  lt;Viewgt;  {  fetching amp;amp; (  lt;Textgt;  loading...  lt;/Textgt;  )  }  {products.map((item)=gt;  lt;Viewgt;  lt;Textgt;  {item.name}  lt;/Textgt;  lt;/Viewgt;)  }  lt;/Viewgt;  )  }  

ТЕПЕРЬ НАШЕ ОБНОВЛЕНИЕ ВЫГЛЯДИТ ТАК

 // Now lets new reducer be function ProductReducer( state={  productsList:[],  fetchingProduct:false },action){ switch(){......} }  // Now our Render component becomes function RenderProducts(){ const {products, fetching} = useSelector((store)=gt;({  products: store.products.productsList,  fetching: store.products.fetchingProduct,  })) return ( lt;Viewgt;  {  fetching amp;amp; (  lt;Textgt;  loading...  lt;/Textgt;  )  }  {products.map((item)=gt;  lt;Viewgt;  lt;Textgt;  {item.name}  lt;/Textgt;  lt;/Viewgt;)  } lt;/Viewgt;  

) }

Теперь второй код вызовет сбой сбоя по одной причине, по которой вы будете пытаться вызвать .карта на неопределенном объекте, почему это происходит, простая причина показана ниже

 // Intial store  const store = {  products:{  products:[], // array of products  fetching: false,  } }  

**Это был наш магазин, хранящийся на диске в виде строки JSON ** ПОСЛЕ НАШЕГО ОБНОВЛЕНИЯ ДО REDUCER наш магазин остается прежним, и до того, как мы получим данные с нашего сервера, чтобы наш редуктор мог записать наше обновление на диск, компонент продукта рендеринга пытается применить наше обновление и, следовательно, сбой

решение

  1. Вы можете очистить магазин // вы не захотите этого, потому что все сохраненные данные, включая токены и жизненно важные данные, будут потеряны, и пользователь запустит приложение заново
  2. Понимание этой проблемы теперь у вас может быть несколько обходных путей, таких как отправка действия для принудительного переноса на диск до того, как ваши компоненты будут отрисованы . вот что я имею в виду, чтобы применить обновление, я сделаю это …
     function ProductReducer(  state={  productsList:[],  fetchingProduct:false  },action){  switch(action.type){  case 'MIGRATING':{  if(store.products){ // checking if products exist on the products   reducer this will handle updates and new installs  state = {...state,productsList:   state.products,fetchingProduct:state.fetching}   }  return state;  }  }  }  

Это приведет к записи изменений на диск, но убедитесь, что это выполняется до того, как ваши компоненты будут отрисованы. Я сделаю это для всех редукторов

  1. Я просто напишу свой компонент, чтобы всегда проверять, доступны ли данные, которые они читают, или же отображать пустые данные, такие как», [], {} для строки, массива и объекта соответственно