Trying to add a listener to an Animated Diff Clamp
in react native to allow the changing of a couple of non animated properties as well.
It initially performs correctly but throws an "illegal node" error when the screen scrolls beyond its max property.
"illegal node ID set as an input for Animated.DiffClamp"
Most articles on this are several years out of date and suggest that you can't add a listener to a diff clamp. However, it does work (now?) but only if declared in the constructor.
Not all situations allow it to be up there as it is not responsive to state changes when not inside render. Inside render it performs fine before reaching max and throwing the error above.
Render () {
const yHeader = Animated.diffClamp(
this.props._yScroll.interpolate({
inputRange: [0, 48],
outputRange: [0, -48],
extrapolateLeft: 'clamp',
}),
-48, 0)
yHeader.addListener(
Animated.event([{value: this.value.ySearch}], {useNativeDriver: false})
)
// this.value.search has been declared in the constructor as an Animated value and is waiting to receive the props. This is not the problem!
}
If still scrolling when the error is thrown, you can see that it continues performing correctly if outputting its current value in console.log despite an "illegal" error completely blocking the screen.
This solves the problem but seems like a highly unnecessary workaround.
It appears we cannot add a listener "legally" to an Animated Diff Clamp when that Diff Clamp is declared in the Render. (Even though we can see it working in console log we get an error covering the screen)
The solution is to take the value of the Diff Clamp and interpolate that into a new variable.
//
const yHeader = Animated.diffClamp(
this.props._yScroll.interpolate({
inputRange: [0, 48],
outputRange: [0, -48],
extrapolateLeft: 'clamp',
}),
-48, 0)
const yHeader_legalised = yHeader.interpolate({
inputRange: [0, 1],
outputRange: [0, 1],
})
yHeader_legalised.addListener(
Animated.event([{value: this.value.ySearch}], {useNativeDriver: false})
)
PS. You will have to lose yHeader_legalised in context in the render in place of yHeader in order for the listener to have something to listen to.