Разница между страницами «TWRP Backup» и «React»

Материал из Home Wiki
(Различия между страницами)
Перейти к навигации Перейти к поиску
 
 
Строка 1: Строка 1:
= Восстановление данных конкретного приложения =


https://www.semipol.de/2016/07/30/android-restoring-apps-from-twrp-backup.html
= Особенности =


First of all - install application.
* В JSX в блоке return стоит оборачивать результат шаблона в ( <div>...</div> ); чтобы избежать проблем с обработчиками js кода, которые вставляют ; сами.
* Ключи помогают React идентифицировать, какой элемент был изменен, добавлен или удален для этого применяется атрибут key в компоненте.
* event.preventDefault(); - выполняет тоже самое, что и onclick="return false;"


Backup of TWRP makes files like this:
= Отладка =
boot.emmc.win
boot.emmc.win.md5
data.ext4.win000
data.ext4.win000.md5
data.ext4.win001
data.ext4.win001.md5
data.ext4.win002
data.ext4.win002.md5
data.info
recovery.log
system.ext4.win
system.ext4.win.md5
system.info


The app data is stored inside the data partition. So the first step is to extract this partition:
https://github.com/facebook/react-devtools
tar -xvf data.ext4.win000


Restart adb on the phone with root permissions:
adb root


Individual application data folders can be pushed to the telephone, e.g.:
= Состояние и жизненный цикл =
adb push data/data/com.example.app /data/data/com.example.app
Локальное состояние является возможностью, доступной только для классов.
https://learn-reactjs.ru/basics/state-and-lifecycle


Android uses a single Unix user per application. First, the pushed files need to become owned bu the user of the application.
Метод componentDidMount() срабатывает после того, как компонент был отрисован в DOM.  


For this purpose, first the user id of the application needs to be found out. For this purpose the application needs to be installed already. On the phone, e.g. through adb shell do:
Когда компонент в какой-то момент удалён из DOM, React вызывает метод componentWillUnmount() жизненного цикла.
dumpsys package com.example.app | grep userId


This will print out the user id of the app, with which the files can be changed:
https://m.habr.com/ru/post/358090/
chown -R $id:$id /data/data/com.example.app


This is still not sufficient for the app to function properly again. If you try to launch the app now, chances are high that it complains about SQLite databases not being readable. This seems to be caused by SELinux, which is used by Android. The SELinux attributes of the files need to be restore, as described here:
== Constructor ==
restorecon -Rv /data/data/com.example.app
ДЕЛАЙТЕ:
* Устанавливайте изначальное состояние компонента
* Если не используется class properties синтаксис – подготовьте все поля класса и вызовете bind на тех функциях, что будут переданы как коллбеки.


Finally, the app should be restored.
НЕ ДЕЛАЙТЕ:
* Не выполняйте никаких сайд-эффектов (side effects) (Вызовы AJAX и т.д.)
 
== [deprecated] componentWillMount ==
ДЕЛАЙТЕ:
* Обновляйте состояние через this.setState
* Выполняйте последние оптимизации
* Вызывайте сайд-эффекты (Вызов AJAX и т.д.) только в случае server-side-rendering.
 
НЕ ДЕЛАЙТЕ:
* Не выполняйте никаких сайд-эффектов (Вызов AJAX и т.д.) на стороне клиента.
 
== [deprecated] componentWillReceiveProps(nextProps) ==
ДЕЛАЙТЕ:
* Синхронизируйте состояние (state) с props
 
НЕ ДЕЛАЙТЕ:
* Не выполняйте никаких сайд-эффектов (Вызовы AJAX и т.д.)
 
== shouldComponentUpdate(nextProps, nextState, nextContext) ==
ДЕЛАЙТЕ:
* Используйте для оптимизации производительности компонента
 
НЕ ДЕЛАЙТЕ:
* Не выполняйте никаких сайд-эффектов (Вызовы AJAX и т.д.)
* Не вызывайте this.setState
 
== [deprecated] componentWillUpdate(nextProps, nextState) ==
ДЕЛАЙТЕ:
* Синхронизируйте состояние (state) с props
 
НЕ ДЕЛАЙТЕ:
* Не выполняйте никаких сайд-эффектов (Вызовы AJAX и т.д.)
 
== componentDidUpdate(prevProps, prevState, prevContext) ==
ДЕЛАЙТЕ:
* Выполняйте сайд-эффекты (Вызовы AJAX и т.д.)
 
НЕ ДЕЛАЙТЕ:
* Не вызывайте this.setState т.к. это будет вызывать циклическую перерисовку.
 
== componentDidCatch(errorString, errorInfo) ==
С помощью этого дополнения вы можете сделать ваш родительский элемент обработчиком ошибок.
 
Когда происходит какая-либо ошибка, эта функция вызывается с следующими параметрами:
* errorString — .toString() сообщение о ошибке
* errorInfo – объект с одним полем componentStack, которое содержит стектрейс, где произошла ошибка.
 
== componentDidMount ==
ДЕЛАЙТЕ:
* Выполняйте сайд-эффекты (Вызовы AJAX и т.д.)
 
НЕ ДЕЛАЙТЕ:
* Не вызывайте this.setState т.к. это вызовет перерисовку.
 
== componentWillUnmount ==
ДЕЛАЙТЕ:
* Удаляйте таймеры и слушателей (listeners) созданных во время жизни компонента.
 
НЕ ДЕЛАЙТЕ:
* Не вызывайте this.setState, не стартуйте новых слушателей или таймеры.
 
== React 16.3+ жизненный цикл компонента ==
=== static getDerivedStateFromProps(nextProps, prevState) ===
Основная ответственность этой новой функции — это убедиться, что состояние (state) и props синхронизированы, когда это необходимо. Ее основной смысл — это замена componentWillRecieveProps.
 
=== getSnapshotBeforeUpdate(prevProps, prevState) ===
Другая из двух новых функций, вызывается в так называемой “pre-commit фазе”, прямо перед изменениями из VDOM, которые должны быть отображены в DOM.
 
=== Устаревшие функции ===
Следующие функции будут маркированы как устаревшие и в следующих релизах переименованы:
* componentWillRecieveProps – UNSAFE_componentWillRecieveProps
* componentWillUpdate – UNSAFE_componentWillUpdate
 
= Controlled <-> uncontrolled input element =
== Проявление ==
Ошибка возникающая в консоли в development-mode:
<syntaxhighlight>
Warning: A component is changing an uncontrolled input of type text to be controlled. Input elements should not switch from uncontrolled to controlled (or vice versa).
Decide between using a controlled or uncontrolled input element for the lifetime of the component.
</syntaxhighlight>
 
Означает, что компонент input был инициализирован в не контролируемом режиме и его переключили в контролируемый (или наоборот).
 
Что же такое uncontrolled mode? Это инициализация input value={undefined}.
 
Как исправить? input value={valueWithUndefinedState || &apos;&apos;}
 
= Detect rerendering =
 
https://stackoverflow.com/questions/41004631/trace-why-a-react-component-is-re-rendering
 
<syntaxhighlight lang="typescript">
public componentDidUpdate(prevProps: any, prevState: any) {
  Object.entries(this.props).forEach(([key, val]) =>
    prevProps[key] !== val && console.log(`Prop '${key}' changed`)
  );
  Object.entries(this.state).forEach(([key, val]) =>
    prevState[key] !== val && console.log(`State '${key}' changed`)
  );
}
</syntaxhighlight>

Версия 11:15, 6 июня 2019

Особенности

  • В JSX в блоке return стоит оборачивать результат шаблона в ( <div>...</div> ); чтобы избежать проблем с обработчиками js кода, которые вставляют ; сами.
  • Ключи помогают React идентифицировать, какой элемент был изменен, добавлен или удален для этого применяется атрибут key в компоненте.
  • event.preventDefault(); - выполняет тоже самое, что и onclick="return false;"

Отладка

https://github.com/facebook/react-devtools


Состояние и жизненный цикл

Локальное состояние является возможностью, доступной только для классов. https://learn-reactjs.ru/basics/state-and-lifecycle

Метод componentDidMount() срабатывает после того, как компонент был отрисован в DOM.

Когда компонент в какой-то момент удалён из DOM, React вызывает метод componentWillUnmount() жизненного цикла.

https://m.habr.com/ru/post/358090/

Constructor

ДЕЛАЙТЕ:

  • Устанавливайте изначальное состояние компонента
  • Если не используется class properties синтаксис – подготовьте все поля класса и вызовете bind на тех функциях, что будут переданы как коллбеки.

НЕ ДЕЛАЙТЕ:

  • Не выполняйте никаких сайд-эффектов (side effects) (Вызовы AJAX и т.д.)

[deprecated] componentWillMount

ДЕЛАЙТЕ:

  • Обновляйте состояние через this.setState
  • Выполняйте последние оптимизации
  • Вызывайте сайд-эффекты (Вызов AJAX и т.д.) только в случае server-side-rendering.

НЕ ДЕЛАЙТЕ:

  • Не выполняйте никаких сайд-эффектов (Вызов AJAX и т.д.) на стороне клиента.

[deprecated] componentWillReceiveProps(nextProps)

ДЕЛАЙТЕ:

  • Синхронизируйте состояние (state) с props

НЕ ДЕЛАЙТЕ:

  • Не выполняйте никаких сайд-эффектов (Вызовы AJAX и т.д.)

shouldComponentUpdate(nextProps, nextState, nextContext)

ДЕЛАЙТЕ:

  • Используйте для оптимизации производительности компонента

НЕ ДЕЛАЙТЕ:

  • Не выполняйте никаких сайд-эффектов (Вызовы AJAX и т.д.)
  • Не вызывайте this.setState

[deprecated] componentWillUpdate(nextProps, nextState)

ДЕЛАЙТЕ:

  • Синхронизируйте состояние (state) с props

НЕ ДЕЛАЙТЕ:

  • Не выполняйте никаких сайд-эффектов (Вызовы AJAX и т.д.)

componentDidUpdate(prevProps, prevState, prevContext)

ДЕЛАЙТЕ:

  • Выполняйте сайд-эффекты (Вызовы AJAX и т.д.)

НЕ ДЕЛАЙТЕ:

  • Не вызывайте this.setState т.к. это будет вызывать циклическую перерисовку.

componentDidCatch(errorString, errorInfo)

С помощью этого дополнения вы можете сделать ваш родительский элемент обработчиком ошибок.

Когда происходит какая-либо ошибка, эта функция вызывается с следующими параметрами:

  • errorString — .toString() сообщение о ошибке
  • errorInfo – объект с одним полем componentStack, которое содержит стектрейс, где произошла ошибка.

componentDidMount

ДЕЛАЙТЕ:

  • Выполняйте сайд-эффекты (Вызовы AJAX и т.д.)

НЕ ДЕЛАЙТЕ:

  • Не вызывайте this.setState т.к. это вызовет перерисовку.

componentWillUnmount

ДЕЛАЙТЕ:

  • Удаляйте таймеры и слушателей (listeners) созданных во время жизни компонента.

НЕ ДЕЛАЙТЕ:

  • Не вызывайте this.setState, не стартуйте новых слушателей или таймеры.

React 16.3+ жизненный цикл компонента

static getDerivedStateFromProps(nextProps, prevState)

Основная ответственность этой новой функции — это убедиться, что состояние (state) и props синхронизированы, когда это необходимо. Ее основной смысл — это замена componentWillRecieveProps.

getSnapshotBeforeUpdate(prevProps, prevState)

Другая из двух новых функций, вызывается в так называемой “pre-commit фазе”, прямо перед изменениями из VDOM, которые должны быть отображены в DOM.

Устаревшие функции

Следующие функции будут маркированы как устаревшие и в следующих релизах переименованы:

  • componentWillRecieveProps – UNSAFE_componentWillRecieveProps
  • componentWillUpdate – UNSAFE_componentWillUpdate

Controlled <-> uncontrolled input element

Проявление

Ошибка возникающая в консоли в development-mode:

Warning: A component is changing an uncontrolled input of type text to be controlled. Input elements should not switch from uncontrolled to controlled (or vice versa).
Decide between using a controlled or uncontrolled input element for the lifetime of the component.

Означает, что компонент input был инициализирован в не контролируемом режиме и его переключили в контролируемый (или наоборот).

Что же такое uncontrolled mode? Это инициализация input value={undefined}.

Как исправить? input value={valueWithUndefinedState || ''}

Detect rerendering

https://stackoverflow.com/questions/41004631/trace-why-a-react-component-is-re-rendering

public componentDidUpdate(prevProps: any, prevState: any) {
  Object.entries(this.props).forEach(([key, val]) =>
    prevProps[key] !== val && console.log(`Prop '${key}' changed`)
  );
  Object.entries(this.state).forEach(([key, val]) =>
    prevState[key] !== val && console.log(`State '${key}' changed`)
  );
}