GeekyAnts / NativeBase

Mobile-first, accessible components for React Native & Web to build consistent UI across Android, iOS and Web.
https://nativebase.io/
MIT License
20.21k stars 2.39k forks source link

Unhandled JS Exception: Cannot read property '_root' of null #739

Closed robinv8 closed 7 years ago

robinv8 commented 7 years ago

Actionsheet error
Actionsheet.js:94:79

rishabh-pandey-sternx commented 7 years ago

@tranren it seem to work fine .Please share the code snippet and the version of NB ,React and RN that you are using .

claudioscheer commented 7 years ago

This is my code:

ActionSheet.show(
    {
        options: [
            'Button 1',
        'Button 2',
        'Close',
        ],
        cancelButtonIndex: 2,
        title: 'Options',
    },
    (index) => {
        this.props.navigator.push({
            id: 'router1',
        });
    },
);

The first time that I call the ActionSheet.show(), it's work fine.

But, when the ActionSheet is closed, and is called for the second time ActionSheet.show(), this error occurs.

error

joaofranca commented 7 years ago

Have exactly the same problem, the crash only occurs after navigating (push), going back and hitting ActionSheet.show again. Tested on iOS.

Edit: Replacing the native-base wrapper and using the react-native ActionSheetIOS instead solves the problem. However, as the name suggests, ActionSheetIOS only works on iOS...

react-native@0.42.3 react@15.5.4 native-base@2.1.0

laukaichung commented 7 years ago

@joaofranca Yes, I'm getting the exact error Cannot read property "_root" of null. The first time it works fine, but it throws the error after navigating back to the page from the actionsheet. I'm testing it on an Android emulator.

laukaichung commented 7 years ago

@GeekRishabh Same error at that line Actionsheet.js:94:79 on Android 5.0 emulator. Open the action sheet , close, open again and get this error:

Image of Error

caroaguilar commented 7 years ago

I'm getting the same error with the Toast. I'm in a screen where after a process is successfully, the application pops back to the previous screen and shows a Toast. When showing that toast I'm getting the error.

Versions: native-base: 2.1.2, react-native: 0.43.3

screen shot 2017-04-25 at 7 29 22 pm

Thanks in advance!

BrianBelhumeur commented 7 years ago

I'm having the same error. I can open and close an ActionSheet as many times as I want, but when I navigate to another scene and then come back, the ActionSheet throws the error "null is not an object (evaluating 'this.actionSheetInstance._root')".

simulator screen shot apr 27 2017 1 55 27 pm

TomMahle commented 7 years ago

I was having this issue in an app based on https://github.com/start-react/native-starter-kit which plays animations between different pages in the app. Each page had its own container, which worked fine in past versions of the starter-kit, but is now breaking because there are animations in which both containers are briefly onscreen. Because of this, the timeline is:

Container 1 Mounts              Unmounts
|-------------------------------|
                            |-----------------------...
                            Container 2 Mounts

As a component unmounts in React, it runs its ref function with 'null'. This is causing the error that we're seeing in this thread, since there is a single class of ActionSheet with an instance bound to it, and the animations between pages mean that the unmount is the most recent ref-defining event, setting it to null.

The fix in my case was to wrap the app in a single container that lives above the AppNavigator and replace the per-page containers with views. A little bit of styling later and the app was back to looking the same and the ActionSheet was working as expected! Hope this is helpful for some of the other people having this issue as well. I'm not sure that there is a good solution to make this more robust within NativeBase, but if there is that would be fantastic.

wkirby commented 7 years ago

The problem seems to be in NativeBase/src/basic/Container.js, specifically line 16 where the singleton instance is set: <ActionSheet ref={ (c) => {ActionSheet.actionsheetInstance = c;}} />. I got around this by setting up my own ActionSheet in the View instead of accessing the singleton instance.

Something like this:

import React, { Component } from 'react';
import { View } from 'react-native';
import { ActionSheet, Button, Text } from 'native-base';

class Foo extends Component {
    constructor(props) {
         super(props);
         this.actionSheet = null;
    }

    render() {
         return (
             <View>
                 <Button onPress={() => this.showActionSheet()}>
                     <Text>Action Sheet!</Text>
                 </Button>
                 <ActionSheet ref={(c) => { this.actionSheet = c; }} />
             </View>
         );
    }

    showActionSheet() {
        if ( this.actionSheet !== null ) {
            // Call as you would ActionSheet.show(config, callback)
            this.actionSheet._root.showActionSheet({options: [1,2,3]}, (i) => console.log(i));
        }
    }
}
seanmadi commented 7 years ago

Having the same exact issue here when calling Toast.show, navigating to another view, navigating back, then calling Toast.show again.

sankhadeeproy007 commented 7 years ago

Fixed with 2.1.5

JaydenR commented 7 years ago

I was still getting this error after updating to 2.1.5, it seems like the component I am using the actionsheet on is only just getting unmounted right before it gets mounted again and the check in Container still thinks it exists.

I managed to get around it by making sure ActionSheet.actionsheetInstance is null when the component unmounts.

public componentWillUnmount () {
    ActionSheet.actionsheetInstance = null;
}

Edit: Actually that didn't fix fully fix my problem, as the components are not being unmounted so I couldn't use Toast on the login if I started on the main screen. Instead I'm setting the actionsheetInstance and toastInstance to null in the willMount of both the login and main screens.

public componentWillMount() { 
    Toast.toastInstance = null;
    ActionSheet.actionsheetInstance = null;
 }
SupriyaKalghatgi commented 7 years ago

27166207-cd384f3c-51b6-11e7-9116-bdb43ba8c431

"dependencies": {
    "native-base": "^2.1.5",
    "react": "16.0.0-alpha.12",
    "react-native": "0.45.1"
  },

@claudioscheer

pankaj-ag commented 7 years ago

Is there any fix for this? My RN Version is 0.44.0 and native-base 2.1.5

sankhadeeproy007 commented 7 years ago

We have again tested it out on our projects again and it is working. Somebody please link me to a repo where I can replicate it. Will be considered resolved otherwise.

pankaj-ag commented 7 years ago

It's working now. Thanks

nimeetshah0 commented 7 years ago

I'm still facing this issue on NB version 2.2.0 and react-native: 0.44.0. It works perfectly first time. Then when I open the app again, it fails.

peterchibunna commented 7 years ago

I get undefined is not an object (evaluating 'this.actionsheetInstance._root')

React: 16.0.0-alpha.12 React native: 0.46.4 Native base: 2.3.1

MY code:

ActionSheet.show({
   ...
});
dinithminura commented 7 years ago

@peterchibunna I got the same issue like you. But it was work properly previously. Now not. Is this affected from another 3rd party library?

peterchibunna commented 7 years ago

@dinithminura it stopped working when I upgraded nativebase module in my application. I can't say it's due to a 3rd party lib.

peterchibunna commented 7 years ago

I've seen what the problem was: @dinithminura. I have to wrap the whole application around <Root> tag.import {Root} from 'native-base' first. It works now.

stephenfromrobin commented 7 years ago

this bug is still unresolved

stephenfromrobin commented 7 years ago

@peterchibunna could you please show a quick example of how to wrap the application using the tag?

pankaj-ag commented 7 years ago
screen shot 2017-08-08 at 8 15 50 pm
stephenfromrobin commented 7 years ago

thanks @pankaj-ag

I'm using a tabbed app component (https://github.com/wix/react-native-navigation)

I can't seem to find where I might wrap with Root- do you have any ideas?

marcusvbp commented 7 years ago

Hi, I have this issue too, with the ActionSheet component.

Gist: https://gist.github.com/marcusvbp/67cf22925cb5fc38aa11f85efc7c7e83

Error Screenshot: https://photos.google.com/share/AF1QipNZUci8yJSwBnOZFZBLMj49EOjxXEEgAQbYZutxf-rUBquGo8WxpfFMLrBoQE8EUQ/photo/AF1QipONDMtbASC_ed16KrX7DT41LvSkIVPtrEniNTwr?key=dk5FX2NEUkhMU2t0c2tLZmtwLWxjenVxSHZNMGdB

How to reproduce: 1 - Open the scene with the avatar-changer component. the ActionSheet works as expected. 2 - close the scene; 3 - open again the scene and now the avatar-changer returns the red screen error.

Package.json:

"native-base": "^2.3.1", "react": "16.0.0-rc.2", "react-native": "0.48.2", "react-native-maps": "^0.16.3", "react-native-router-flux": "^4.0.0-beta.21",

shivrajkumar commented 7 years ago

@marcusvbp Make sure to wrap the app with Root component so that the app doesn't lose actionsheet instance on closing any scene

marcusvbp commented 7 years ago

@shivrajkumar hi, the Root component is needed in all scenes with native-base elements or only in the avatar-changer.js component?

Thanks.

marcusvbp commented 7 years ago

@shivrajkumar I have wrapped my register.js component with the Root component but the error persists.

I have tested all theses cases, and all returns the same error:

1 - Root component in scene component (register.js) and the avatar-changer.js 2 - Root component in scene comp but not in the avatar-changer.js 3 - Root component only in the avatar-changer.js

agungjk commented 7 years ago

thanks @peterchibunna working for me

pedrogarciyalopez commented 7 years ago

@stephenfromrobin hi! I have the same problem with the wix/react-native-navigation. Did you solve it?

stephenfromrobin commented 7 years ago

@pedrogarciyalopez Sorry, I still haven't found a solution!

peterchibunna commented 7 years ago

Wrap your whole application within <Root>. It's in the docs.

kesiena115 commented 6 years ago

@wkirby solution helped me figure out a simpler solution that fixed this bug for me for both Toast and ActionSheet. I added the following code to my topmost component (i.e., the same file where I wrapped my whole application with <Root />).

import { Toast, ActionSheet } from 'native-base';

componentWillUnmount() {
      Toast.toastInstance = null;
      ActionSheet.actionsheetInstance = null;
}

To understand why this works, look at render() in native-base/src/basic/Root.js. My change simply ensures that the Toast and ActionSheet get reinitialized the next time the user reopens the app. Please let me know if anyone has a better solution.

peterchibunna commented 6 years ago

@marcusvbp the problem is still there because Root is supposed to be the root component. All your whole application should be wrapped within the Root container. Not wrapping the individual screens.

marcusvbp commented 6 years ago

@peterchibunna thanks, I get it now :)

refucktor commented 6 years ago

Same issue but with the Toast, even after wrapping my entire app inside <Root/> still I got the same error screen.

Here is my entry point

import React from 'react';
import { Platform } from 'react-native';
import { Root } from 'native-base';
import { StackNavigator } from 'react-navigation';
import { AppRoutes } from './AppRoutes';
import HomeScreen from './HomeScreen';

const AppNavigator = StackNavigator(
    {
        ...AppRoutes,
        HomeScreen: { screen: HomeScreen },
    }, {
        initialRouteName: 'HomerScreen',
        headerMode: 'none',
        mode: Platform.OS === 'ios' ? 'modal' : 'card',
    },
);

export default () =>
    <Root>
        <AppNavigator/>
    </Root>;

here is my dummy HomeScreen when I'm trying to use Toast

import { Button, Container, Text, Toast } from 'native-base';
import React from 'react';
import { View } from 'react-native';

export default class HomeScreen extends React.Component {

    render() {
        return (
            <Container>
                <View>
                    <Button
                        full rounded
                        onPress={Toast.show({
                            text: 'here',
                            position: 'bottom',
                            buttonText: 'OK',
                        })}
                    >
                        <Text>Show me</Text>
                    </Button>
                </View>
            </Container>
        );
    }
}

Can any of you suggest me something, please....

SupriyaKalghatgi commented 6 years ago

@refucktor Please check for this implementation in NativeBase KitchenSink

rooque commented 6 years ago

@kesiena115 this worked for me as well, thank you! :smile:

My top most component looks like this right now:

import { Root, Toast } from 'native-base';
export default class AppComp extends Component {

  componentWillUnmount() {
    Toast.toastInstance = null;
  }

  render() {
    return (
      <Provider store={store}>
        <Root>
          <Routes />
        </Root>
      </Provider>
    )
  }
}
cristian-milea commented 6 years ago

thanks @rooque !

kesiena115 commented 6 years ago

My previous suggestion above eventually gave me problems. The ActionSheet would suddenly stop working after a few days i.e., it won't show when I click on the button that's meant to display it. I don't know what was causing this and frankly, I got tired of trying to fix this component. I eventually switched to react-native-modal a few weeks ago as a replacement for the ActionSheet. Best decision ever!

SupriyaKalghatgi commented 6 years ago

@kesiena115

The ActionSheet would suddenly stop working after a few days i.e., it won't show when I click on the button that's meant to display it.

We have not faced it so far, how can that work today and not tomorrow?

manish-appface commented 6 years ago

What does it mean " wrap your topmost component inside <Root> from native-base".I am unable to do this . please give me sample code for toast.

akhil-ga commented 6 years ago

@manish-appface See example for Actionsheet here

manish-appface commented 6 years ago

@akhil-geekyants It helped.Thank you.

pisangGoreng commented 6 years ago

Wrap your all tags in render method with , its work for me

josepht1 commented 6 years ago

@rooque, your solution worked for me.

trajakovic commented 6 years ago

actually, none of solutions work. (testing on Android 7)

If you put down application with back-button, then switch again to application, first you get warning about ToastContainer (yellow screen), described in #819 . And if you try to show toast, you got this error.

In my case, root component is StyleProvider then Root, but it doesnt matter, I've tryed all permutations with same result - this error.

I can only guess that 'static' saving instance of Root (in Root) is not best way to deal with. And maybe RN is doing something strange and different when starting application for the first time, and re-opening application (from background).