Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Returning null or false from render within SVG hierarchy crashes app #84

Closed
steveliles opened this issue Jul 22, 2016 · 3 comments
Closed

Comments

@steveliles
Copy link
Contributor

steveliles commented Jul 22, 2016

When building React components it is very convenient to be able to return null (or false) when you don't want to render anything. This is a documented feature of React.

However, returning null or false from the render method of a component nested somewhere within an Svg hierarchy fails (at least on iOS - I didn't try with Android yet).

The failure mode is different depending on whether a falsy value is returned in the initial render or a subsequent render that changes the output from a renderable component to a falsy value.

For example, the following crashes the app immediately (app completely shuts down and exits to home screen):

const MyComponent = ({hide}) => {
  return null
}

const MySVG = () => {
  return (
    <View style={style}>
      <Svg width={100} height={100}>
        <MyComponent/>
      </Svg>
    </View>
  )
}

If a state or props change causes a render method to start returning falsy values where it previously returned SVG components an exception is thrown, for example:

class MyComponent extends Component {
  constructor(props){
    super(props)
    this.state = {
      oops: false
    }
  }
  componentDidMount(){
    this.setState({oops:true})
  }
  render(){
    if (this.state.oops){
      return null
    } else {
      return <Circle cx={10} cy={10} r={5} stroke='#0f0' strokeWidth={2}/>
    }
  }
}

const MySVG = () => {
  return (
    <View style={style}>
      <Svg width={100} height={100}>
        <MyComponent/>
      </Svg>
    </View>
  )
}

The exception this produces is:

Exception 'shadowView (for ID 554) not found' was thrown while invoking replaceExistingNonRootView on target RCTUIManager with params ( 554, 555 )

My current workaround is instead of returning null, return a <Nothing/> component defined as:

const MyComponent = () => {
  return <G/>
}
@magicismight
Copy link
Collaborator

Thanks for reporting this.
I`ll try to get this been fixed maybe within next version.

@mattsenior
Copy link

Hi @magicismight and @steveliles, I seem to be encountering the second of these two issues as well - an exception similar to: Exception 'shadowView (for ID 554) not found' was thrown while invoking replaceExistingNonRootView on target RCTUIManager with params ( 554, 555 )

As mentioned in the original issue, It occurs when render returns null if it previously rendered a component - as per the this.setState({oops:true}) example above.

There is no error if the component initially renders null and then subsequently renders a component such as Circle.

I’ve also noticed the same exception is thrown if the element I return is of a different type from the one previously rendered, e.g. changing Rect -> Circle or Circle -> Rect:

render(){
    if (this.state.oops){
      return <Rect width="100" height="100" fill="blue" />
    } else {
      return <Circle cx={10} cy={10} r={5} stroke='#0f0' strokeWidth={2}/>
    }
  }

So it seems that:

falsy -> Circle // Ok
Circle -> falsy // Error
Circle -> Circle // Ok
Circle -> Rect // Error

Versions

react@15.3.2
react-native@0.36.0
react-native-svg@4.3.1

If you have any ideas or if I might be doing something stupid please let me know 😄
Thanks, Matt

@nicotroia
Copy link

Having the same issue with "react-native-svg": "^5.2.0" but I can workaround this problem by toggling the SVG element fillOpacity and strokeOpacity instead of returning null for the component. Hopefully this will help someone

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants