react-native-blur icon indicating copy to clipboard operation
react-native-blur copied to clipboard

Android invalid viewRef and circular structure

Open bdanis opened this issue 7 years ago • 4 comments

currently having issues with the rendering on Android for one, I get index.android.bundle:9099 Warning: Failed prop type: Invalid prop viewRef of type object supplied to BlurView, expected number. in BlurView

then i get into a circular structure error, from what I can tell, my blurview is outside of the target.

Works fine on ios though

<View style={styles.app.container}> <View ref={ (ref) => { if (ref) this.screen = ref; this.setState({referenceReady: true}); } } style={styles.app.container}> {content} </View> {this.screen ? <BlurView viewRef={this.screen} style={{position: 'absolute', top:0, left: 0, bottom: 0, right: 0}} blurType="dark" blurAmount={10}/> : null} </View>

bdanis avatar Oct 19 '17 14:10 bdanis

Same problem here. Code is very similar:

<View>
    <ScrollView>
        <View ref={ ref => { this._scrollViewRef = ref; }}>
            { other views, etc }
        </View>
    </ScrollView>
    { this.state.shouldShowModal && this._scrollViewRef && (
        <BlurView
            style={{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0 }}
            blurType="light"
            blurAmount={ 10 }
            viewRef={ this._scrollViewRef }
         />
      ) }

Error 1 (warning): Warning: Failed prop type: Invalid prop 'viewRef' of type 'object' supplied to 'BlurView', expected 'number' This is odd, since in my understanding a ref is always supposed to be an object and when I log it out it is, even on Android.

Error 2 (fatal):

10-30 11:47:46.353 5378-5421/my.app.name E/ReactNativeJS: JSON.stringify cannot serialize cyclic structures
10-30 11:47:46.355 5378-5421/my.app.name I/ReactNativeJS: 'Failed to print error: ', 'C++ exception in \'nativeFlushQueueImmediate\'\n\nDid not get valid calls back from JS...
10-30 11:47:46.355 5378-5421/my.app.name E/ReactNativeJNI: Got JS Exception: Exception calling object as function: JSON.stringify cannot serialize cyclic structures.

Note that in mine the BlurView is neither a child nor a parent of the blurred element.

beneichler avatar Oct 30 '17 18:10 beneichler

I have the same issueC++ exception in 'nativeFlushQueueImmediate'\n\nDid not get valid calls back from JS

hectorsuarezm avatar Dec 02 '17 18:12 hectorsuarezm

I was able to make this work on Android by doing the following (all good on iOS):

Drawer (more or less the same happens in my Stack Navigator):

constructor(props) {
	super(props);
	this.state = {
		viewRef: 0
	};
}
...
componentDidMount(){
	setViewRef = setTimeout(function(){
		this.setState({ viewRef: global.HomeView });
	}.bind(this), 2000);
}
...
componentWillUnmount(){
	clearTimeout(this.setViewRef);
}
...
render() {
	return (
		<ScrollView>
			<BlurView style={styles.absolute} viewRef={this.state.viewRef} blurType="dark" blurAmount={10} />
			<SafeAreaView>
			...
			</SafeAreaView>
		</ScrollView>
	)
}
```	

**Home** screen (the ref I need):

import ReactNative, { findNodeHandle, ... } from 'react-native'; ... componentDidMount() { global.HomeView = ReactNative.findNodeHandle(this.HomeView); } ... render() { return ( <View ref={component => this.HomeView = component}> ... </View> ) }


I am using `global` because I need the _Home_ view reference in the _Drawer_ and _Stack_ Navigators which are rendered before. The reason I'm also using `setTimeout()` - Honestly I don't know another way to do it and haven't tried it with _Redux_ (which might be a possibility) - Let me know of a better way.

One weird thing is that I wasn't able to get a value out of `ReactNative.findNodeHandle` while trying to use `this.refs.HomeView` or even `this.state.HomeView` instead (in the Home screen).

Also note that the _ref_ number will be different for any code change you do and even appears to be completely random at times, so no point in hard-coding it.

Overall I find the experience on Android very poor comparing to iOS, as it clearly takes a snapshot of what's in the background.

I hope this helps!

gesf avatar Feb 19 '18 01:02 gesf

I was able to make this work on Android by doing the following (all good on iOS):

Drawer (more or less the same happens in my Stack Navigator):

constructor(props) {
	super(props);
	this.state = {
		viewRef: 0
	};
}
...
componentDidMount(){
	setViewRef = setTimeout(function(){
		this.setState({ viewRef: global.HomeView });
	}.bind(this), 2000);
}
...
componentWillUnmount(){
	clearTimeout(this.setViewRef);
}
...
render() {
	return (
		<ScrollView>
			<BlurView style={styles.absolute} viewRef={this.state.viewRef} blurType="dark" blurAmount={10} />
			<SafeAreaView>
			...
			</SafeAreaView>
		</ScrollView>
	)
}

Home screen (the ref I need):

import ReactNative, { findNodeHandle, ... } from 'react-native';
...
componentDidMount() {
	global.HomeView = ReactNative.findNodeHandle(this.HomeView);
}
...
render() {
	return (
	  <View ref={component => this.HomeView = component}>
		...
	  </View>
	)
}

I am using global because I need the Home view reference in the Drawer and Stack Navigators which are rendered before. The reason I'm also using setTimeout() - Honestly I don't know another way to do it and haven't tried it with Redux (which might be a possibility) - Let me know of a better way.

One weird thing is that I wasn't able to get a value out of ReactNative.findNodeHandle while trying to use this.refs.HomeView or even this.state.HomeView instead (in the Home screen).

Also note that the ref number will be different for any code change you do and even appears to be completely random at times, so no point in hard-coding it.

Overall I find the experience on Android very poor comparing to iOS, as it clearly takes a snapshot of what's in the background.

I hope this helps!

what is global.HomeView ?

pbthakre avatar Jan 22 '19 12:01 pbthakre