React-native: сохранить анимированные значения в состоянии или как свойство класса?
Лучше ли поддерживать анимированное значение (fadeAnim
) как свойство состояния или нормально ли оно превращаться в свойство класса?
Пример:
class ModalShade extends React.Component {
fadeAnim = new Animated.Value(0)
render() {
return (
<Animated.View
cls="bg-black absolute-fill"
style={{ opacity: this.fadeAnim }}
/>
)
}
componentDidMount() {
Animated.spring(
this.fadeAnim, {
toValue: 0.6,
tension: 100,
friction: 20
}
).start();
}
}
Разъяснение:
Я знаю, что государство используется для реагирования на сверку. React-native 'Animated
обходят обычный рендер(), поэтому компонент обновляется даже тогда, когда не изменяется состояние.
Я не вижу смысла сравнивать Animated.Value
в моем shouldComponentUpdate
, поэтому я переместил его из состояния.
Ответы
Ответ 1
Лучше следовать официальной документации и использовать свойство штата.
Для этого есть две веские причины:
- Вы хотите сохранить все, что влияет на результат рендеринга компонента в вашем состоянии/реквизите/контексте.
- Реагирующая анимационная библиотека имеет свои собственные оптимизации, позволяющие избегать вызовов
setState
и повторной рендеринга при изменении Анимированных компонентов. Это цитата из официальной документации.
Когда компонент монтируется, opacity устанавливается равным 0. Затем активируется анимация ослабления в анимированном значении fadeAnim, которая обновляет все зависимые сопоставления (в данном случае, только непрозрачность) на каждом кадре, как value оживляет конечное значение 1.
Это делается оптимизированным способом, который быстрее, чем вызов setState и повторной рендеринга.
Ответ 2
В целом, с React существует большая разница между сохранением чего-либо как свойства instance/class (например, this.myVar = 'foo';) или в состоянии. Разница заключается в том, что React использует объект state, чтобы определить, когда повторно выполнить рендеринг компонента (то есть снова вызвать render()).
Если вы храните переменную как свойство class/instance, а затем вы ее изменяете, React render logic ничего не знает об этом изменении и, как следствие, вы не увидите никаких изменений в визуализированном пользовательском интерфейсе.
Таким образом, вы должны хранить в состоянии вещи, которые изменяют выводимый результат компонента. Если переменная вообще не влияет на выводимый вывод (и вы не хотите получать уведомление, когда оно изменяется в основном), вы можете сохранить его как свойство instance/class. Иногда это может иметь лучшие последствия для производительности, поскольку вызов setState
для обновления этой переменной приведет к ненужному рендерингу.
В вашем примере примера вы опустили метод рендеринга, но очень вероятно, что вам нужно получить доступ к переменной fadeAnim
в состоянии, чтобы фактически выполнить анимацию. В основном, Animated.spring просто интерполирует некоторые значения с течением времени, но тогда вам нужно использовать эти интерполированные значения, чтобы реально что-то оживить.
В примере документа (https://facebook.github.io/react-native/docs/animated.html) вы можете видеть, что this.state.fadeAnim
используется внутри render
для управления (анимировать) стиль непрозрачности.
Чтобы повторить, вам нужно сохранить fadeAnim
в конкретном состоянии, потому что изменение значения должно вызвать повторную визуализацию.