react-stack-navigation
Version:
Library that facilitates navigation between screens to react natively
130 lines (117 loc) • 3.57 kB
JavaScript
import React from 'react';
import {BackHandler, View} from 'react-native';
export const StackNavigation = (routes, config) => {
return () => <Navigator routes={routes} config={config}/>;
}
export default class Navigator extends React.Component {
stack = []
constructor(props) {
super(props);
this.pages = []
const {routes, config} = this.props
const {initial} = config
this.pages[initial] = this.create(routes[initial], this.getNavigation())
this.stack.push(initial)
this.renderPage(() => {
this.setState({page: initial})
})
this.state = {
page: initial
}
}
renderPage = (call) => {
this.elements = []
const {routes, config} = this.props
const {initial} = config
setTimeout(() => {
Object.keys(routes).map(key => {
this.elements[key] = routes[key]
this.pages[key] = this.create(routes[key], this.getNavigation());
})
if (call) {
call()
}
}, 1)
}
getNavigation = () => ({
navigation: {
push: this.push,
replace: this.replace,
goBack: this.goBack,
pushClen: this.pushClean
}
})
pushClean = (page, params) => {
this.stack = []
this.push(page, params)
}
push = (page, params) => {
if (this.state.page == page) {
return
}
this.stack.push(page)
if (params != null) {
let nav = this.getNavigation()
nav.navigation = {...nav.navigation, params: params}
this.pages[page] = this.create(this.elements[page], nav)
}else{
this.pages[page] = this.create(this.elements[page], this.getNavigation())
}
this.navigate(page)
}
replace = (page, params) => {
if (this.state.page == page) {
return
}
let sizeStack = this.stack.length
this.stack = this.stack.slice(0, sizeStack - 1)
this.stack.push(page)
if (params) {
alert('ds')
this.pages[page] = this.create(this.elements[page], {...params, ...this.getNavigation()})
}
this.navigate(page)
}
goBack = () => {
let sizeStack = this.stack.length
let newSize = sizeStack - 1
this.stack = this.stack.slice(0, newSize)
if (newSize == 0) {
BackHandler.exitApp()
}
this.navigate(this.stack[newSize - 1])
}
create = (el, props) => {
return React.createElement(el, props)
}
componentDidMount() {
this.backHandler = BackHandler.addEventListener('hardwareBackPress', this.handleBackPress);
}
componentWillUnmount() {
this.backHandler.remove()
}
handleBackPress = () => {
let sizeStack = this.stack.length
if (sizeStack == 1) {
return false
}
let newSize = sizeStack - 1;
this.stack = this.stack.slice(0, newSize)
this.navigate(this.stack[newSize - 1])
return true;
}
navigate = (page) => {
this.setState({page});
}
render() {
return (<View style={{flex: 1}}>
{
Object.keys(this.pages).map((key, i) => {
return <View key={i} style={{display: key == this.state.page ? null : 'none', flex: 1}}>
{this.pages[key]}
</View>
})
}
</View>)
}
}