#javascript #reactjs #react-native #react-navigation
Вопрос:
Я создаю собственный экран React, в котором непрозрачность содержимого зависит от текущего состояния прокрутки:
state = {
scroll: new Animated.Value(0)
}
constructor(props) {
super(props)
}
componentDidMount() {
const { scroll } = this.state
scroll.addListener(({ value }) => (this._value = value))
}
renderForeground = () => {
const { scroll } = this.state
const titleOpacity = scroll.interpolate({
inputRange: [0, 106, 154],
outputRange: [1, 1, 0],
extrapolate: 'clamp'
})
return (
<View style={styles.foreground}>
<Animated.View style={{ opacity: titleOpacity }}>
<Text style={styles.message}>Do you have time to play?</Text>
</Animated.View>
</View>
)
}
render() {
const { scroll } = this.state
return (
<StickyParallaxHeader
foreground={this.renderForeground()}
scrollEvent={Animated.event([{ nativeEvent: { contentOffset: { y: scroll } } }])} />
)
}
Теперь я пытаюсь установить ту же непрозрачность (titleOpacity, рассчитанную в функции renderForeground ()) для заголовка заголовка навигации. Моя идея состояла в том, чтобы преобразовать значение непрозрачности в шестнадцатеричное значение и установить цвет заголовка следующим образом:
this.props.navigation.setOptions({headerTintColor: "#ffffff" alpha_value})
Чтобы синхронизировать это значение alpha_value с titleOpacity, я хотел использовать setState в функции renderForeground() :
const { scroll } = this.state
const titleOpacity = scroll.interpolate({
inputRange: [0, 106, 154],
outputRange: [1, 1, 0],
extrapolate: 'clamp'
})
this.setState({headerOpacity: titleOpacity})
Однако план здесь уже проваливается, так как я получаю следующую ошибку:
Превышена максимальная глубина обновления. Это может произойти, когда компонент повторно вызывает setState внутри componentWillUpdate или componentDidUpdate. React ограничивает количество вложенных обновлений, чтобы предотвратить бесконечные циклы
Есть ли другой способ синхронизировать состояние прокрутки и цвет заголовка заголовка?
Комментарии:
1. Установка состояния вызывает повторный рендеринг, поэтому, если рендеринг компонента вызывает состояние набора, вы получите бесконечный цикл. Просто не используйте состояние для непрозрачности; вычислите его, а затем используйте напрямую.
Ответ №1:
Вы не должны вызывать setState внутри render(), так как это запускает повторную отправку компонента, запуск setState(), запуск повторной отправки и т. Д. Это и есть причина ошибки, которую вы получаете.
Если заголовок находится в одном и том же компоненте, как кажется с момента использования setState
, то вы можете передать интерполированное значение из вашего метода визуализации обоим компонентам:
render() {
const { scroll } = this.state
const titleOpacity = scroll.interpolate({
inputRange: [0, 106, 154],
outputRange: [1, 1, 0],
extrapolate: 'clamp'
})
return (
<>
<Header titleOpacity={titleOpacity} />
<StickyParallaxHeader
foreground={this.renderForeground(titleOpacity)}
scrollEvent={Animated.event([{ nativeEvent: { contentOffset: { y: scroll } } }])} />
</>
)
}
Комментарии:
1. В этом есть большой смысл! Проблема в том, что у меня нет компонента заголовка, я использую заголовок навигации React, который я могу (насколько мне известно) изменять только с помощью «this.props.navigation.setOptions ()». Итак, вопрос в том, где/как я вызываю эту функцию?