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

Stack Navigator #73

Closed
nephix opened this issue Jul 24, 2017 · 26 comments
Closed

Stack Navigator #73

nephix opened this issue Jul 24, 2017 · 26 comments

Comments

@nephix
Copy link

nephix commented Jul 24, 2017

Issue Description

When I use StackNavigator with enabled header, the react-native-dropdownalert is displayed below the header and not at the top of the screen.

Steps to Reproduce / Code Snippets

  1. Implement StackNavigator example
  2. Implement react-native-dropdownalert
  3. Trigger the drop down

Drop down alert below header

Expected Results

There should be a prop for the drop down alert to overlay above the header.

Additional Information

  • React Native version: 0.45.1
  • react-native-dropdownalert version: 2.10.0
  • Platform(s) (iOS, Android, or both?): iOS
@testshallpass
Copy link
Owner

Hi @nephix If you disable the StackNavigator header, does it work as expected? It appears that the dropdown alert is a child of StackNavigator, is that correct? There are startDelta and endDelta props that can change the dropdown alert position, perhaps these might help.

@nephix
Copy link
Author

nephix commented Jul 26, 2017

Hi testshallpass,

yes the dropdown alert is within the StackNavigator. I tried to workaround that with startDelta and endDelta but I was not able to render the dropdown "above" of the StackNavigator's header.

I worked around this by hiding the StackNavigator's header just before displaying the dropdown alert

@testshallpass
Copy link
Owner

Hi @nephix I was able to reproduce. It appears that react-navigation wraps it's contents in like a container. I reported to react-navigation to get some assistance: react-navigation/react-navigation#2423

@ricardokdz
Copy link

+1

1 similar comment
@manaka02
Copy link

manaka02 commented Sep 7, 2017

+1

@slpereira
Copy link

This problem is happening to me as well. @testshallpass your issue on react-navigation was closed without any response, is there any workaround in this issue?

@testshallpass
Copy link
Owner

@slpereira I'm looking into workaround or solution.

@szantogab
Copy link

szantogab commented Sep 19, 2017

@testshallpass @slpereira @nephix Actually the solution is pretty straightforward. You need to place the DropdownAlert ABOVE the StackNavigator.

I do it like this:

export class App extends React.Component {
    render() {
        return (
            <View style={{width: '100%', height: '100%'}}>
                <Nav/>
                <DropdownAlert ref={(ref) => DropDownHolder.setDropDown(ref)}/>
            </View>
        )
    }
}

Here Nav is your component that you want to start the application with, in our case a StackNavigator.
I have a DropDownHolder in this solution to save this dropdown reference for the entire app, so every component can access it:

export class DropDownHolder {
    static dropDown;

    static setDropDown(dropDown) {
        this.dropDown = dropDown;
    }

    static getDropDown() {
        return this.dropDown;
    }
}

Hope this helps. :)

@nephix
Copy link
Author

nephix commented Sep 19, 2017

Thanks a lot @szantogab!

@testshallpass
Copy link
Owner

Thanks @szantogab Do you mind if I create a gist from your example and link it on README?

@szantogab
Copy link

@testshallpass Of course not. Go ahead! :)

@herarya
Copy link

herarya commented Oct 3, 2017

@szantogab that worked! Thanks so much!

@SheppardX
Copy link

SheppardX commented Nov 16, 2017

with router flux i cant do your fix because i have this as my start

`

     let middleware = [
	Analytics,
	thunk, // Allows action creators to return functions (not just plain objects)
];

if (__DEV__) {
  // Dev-only middleware
	middleware = [
		...middleware,
		logger(), // Logs state changes to the dev console
	];
}

// Init redux store (using the given reducer & middleware)
const store = compose(
  applyMiddleware(...middleware),
)(createStore)(rootReducer);

/* Component ==================================================================== */
// Wrap App in Redux provider (makes Redux available to all sub-components)
export default function AppContainer() {
	return (
		<Provider store={store}>
			<RouterWithRedux scenes={AppRoutes} style={AppStyles.appContainer} />
		</Provider>
	);
}

`

can u help me ? i have the same issue

@SheppardX
Copy link

@szantogab Your really helped me with redux + router flux ... i used the same method


export default function AppContainer() {
	return (
		<View style={AppStyles.container}>
			<Provider store={store}>
				<RouterWithRedux scenes={AppRoutes} style={AppStyles.appContainer}/>
			</Provider>
			<DropdownAlert ref={ref => DropDownHolder.setDropDown(ref)} closeInterval={6000}/>
		</View>
	);
}

And it works perfectly

@maharjanaman
Copy link

@szantogab great way to make it available on every component. But how can I trigger alertWithType on componentDidMount or componentWillMount? As it seems during this lifecycle refs has not been set or something. Is there some way to achieve this?

@szantogab
Copy link

@maharjanaman If you use DropdownHolder mentioned above, you can get a reference to the dropdown by doing DropdownHolder.getDropdown().alertWithType(....)

@maharjanaman
Copy link

@szantogab I'm try to show alert as soon as screen loads i.e. on componentDidMount. But when trying to call alertWithType(...) in componentDidMount method it gives error TypeError: undefined is not an object (evaluating 'DropDownHolder.getDropDown().alertWithType')

@xmannv
Copy link

xmannv commented May 11, 2018

@szantogab can you show more to control the onClose property in other component, feel like:

<DropdownAlert ref={ref => DropDownHolder.setDropDown(ref)} onClose={DropDownHolder.onClose}/>

And in my DropDownHoler:

export class DropDownHolder {
  static dropDown
  static onClose

  static setDropDown (dropDown) {
    this.dropDown = dropDown
  }

  static getDropDown () {
    return this.dropDown
  }

  static setOnClose(onClose) {
    this.onClose = onClose
  }
}

In my component, i tried but seem like it didn't work with onClose

DropDownHolder.setOnClose(
() => {        
alert('did u call me')
 console.log('call me')
}
)

@nhatmai3686
Copy link

nhatmai3686 commented May 24, 2018

Thanks @szantogab

@stereodenis
Copy link

stereodenis commented Jul 7, 2018

@xmannv my variant with typescript types

type AlertType = 'info' | 'warn' | 'error' | 'success'

export type DropdownType = {
  alertWithType: (type: AlertType, title: string, message: string) => void
}

export class DropDownHolder {
  static dropDown: DropdownType

  static setDropDown(dropDown: DropdownType) {
    this.dropDown = dropDown
  }

  static alert(type: AlertType, title: string, message: string) {
    this.dropDown.alertWithType(type, title, message)
  }
}

so I just call DropDownHolder.alert('error', 'Title', 'error message')

@testshallpass testshallpass changed the title Drop down alert & Stack Navigator Stack Navigator Jul 9, 2018
@testshallpass
Copy link
Owner

Added documentation to README with gists examples to help with StackNavigator. PR update readme with caveats #147

@abdul-elah-js
Copy link

how do you access the dropdown holder from another component ? @szantogab

@Aidenkwok
Copy link

+1

@brianinator
Copy link

@abdul-elah-js import DropDownHolder from './DropDownHolder' then use it as described DropDownHolder.getDropDown().alertWithType(....)

@berk9595
Copy link

berk9595 commented Oct 6, 2019

You just need to pass the ref to other components.

class App extends React.Component{
    render(){
        return(
            <ApolloProvider client={client}>
                <MyContainer screenProps={{dropDownAlertRef: this.dropDownAlertRef}}/>
                <DropdownAlert ref={ref => (this.dropDownAlertRef = ref)} />
            </ApolloProvider>
        )
    }
}

class MyContainer extends React.Component {
    render(){
        return(
           <TouchableOpacity
                  onPress={() => {
                   this.props.screenProps.dropDownAlertRef.alertWithType(
                  'success',
                  'Succes !!',
                  'Something nice !!',
                );
           }}>
           <Text>
            Trigger Alert !
           </Text>
        </TouchableOpacity>
               )
    }
}

@afizboltz
Copy link

afizboltz commented Dec 20, 2021

@xmannv my variant with typescript types

type AlertType = 'info' | 'warn' | 'error' | 'success'

export type DropdownType = {
  alertWithType: (type: AlertType, title: string, message: string) => void
}

export class DropDownHolder {
  static dropDown: DropdownType

  static setDropDown(dropDown: DropdownType) {
    this.dropDown = dropDown
  }

  static alert(type: AlertType, title: string, message: string) {
    this.dropDown.alertWithType(type, title, message)
  }
}

so I just call DropDownHolder.alert('error', 'Title', 'error message')

hi, may I know did you put DropDownHolder as a component ?
where you call this code

import DropdownAlert from 'react-native-dropdownalert';

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

No branches or pull requests