#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 наш магазин остается прежним, и до того, как мы получим данные с нашего сервера, чтобы наш редуктор мог записать наше обновление на диск, компонент продукта рендеринга пытается применить наше обновление и, следовательно, сбой
решение
- Вы можете очистить магазин // вы не захотите этого, потому что все сохраненные данные, включая токены и жизненно важные данные, будут потеряны, и пользователь запустит приложение заново
- Понимание этой проблемы теперь у вас может быть несколько обходных путей, таких как отправка действия для принудительного переноса на диск до того, как ваши компоненты будут отрисованы . вот что я имею в виду, чтобы применить обновление, я сделаю это …
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; } } }
Это приведет к записи изменений на диск, но убедитесь, что это выполняется до того, как ваши компоненты будут отрисованы. Я сделаю это для всех редукторов
- Я просто напишу свой компонент, чтобы всегда проверять, доступны ли данные, которые они читают, или же отображать пустые данные, такие как», [], {} для строки, массива и объекта соответственно