Skip to content

Instantly share code, notes, and snippets.

@heygema
Created June 10, 2020 16:01
Show Gist options
  • Save heygema/eb8a831014a422268ea9411ee448ff59 to your computer and use it in GitHub Desktop.
Save heygema/eb8a831014a422268ea9411ee448ff59 to your computer and use it in GitHub Desktop.
nih josh
import React from 'react';
import {View, StyleSheet, Button} from 'react-native';
import {Navigator, Route} from './Navigator';
function Screen1({navigator}) {
return (
<View style={[styles.screen, {backgroundColor: '#59C9A5'}]}>
<Button title="Screen 2" onPress={() => navigator.push('Screen2')} />
<Button title="Pop" onPress={() => navigator.pop()} />
</View>
);
}
function Screen2({navigator}) {
return (
<View style={[styles.screen, {backgroundColor: '#23359B'}]}>
<Button title="Screen 3" onPress={() => navigator.push('Screen3')} />
<Button title="Pop" onPress={() => navigator.pop()} />
</View>
);
}
function Screen3({navigator}) {
return (
<View style={[styles.screen, {backgroundColor: '#B9E3C6'}]}>
<Button title="Pop" onPress={() => navigator.pop()} />
</View>
);
}
function App() {
return (
<Navigator>
<Route name="Screen1" component={Screen1} />
<Route name="Screen2" component={Screen2} />
<Route name="Screen3" component={Screen3} />
</Navigator>
);
}
const styles = StyleSheet.create({
screen: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
});
export default App;
import React, {useState, useCallback, useEffect} from 'react';
import {View, StyleSheet, Animated, Dimensions} from 'react-native';
let {width} = Dimensions.get('window');
export const _buildSceneConfig = (children = []) => {
const config = {};
children.forEach(child => {
config[child.props.name] = {
key: child.props.name,
component: child.props.component,
};
});
return config;
};
export function Route() {
return null;
}
export function Navigator(props) {
let initialSceneName = props.children[0].props.name;
let [sceneConfig] = useState(_buildSceneConfig(props.children));
let [stack, setStack] = useState([sceneConfig[initialSceneName]]);
let [lastAction, setActionHistory] = useState(null);
let [animatedValue] = useState(new Animated.Value(0));
let push =
sceneName => {
setStack(_ => {
return [...stack, sceneConfig[sceneName]];
});
setActionHistory('PUSH');
}
let pop =
_ => {
Animated.timing(animatedValue, {
toValue: width,
duration: 250,
useNativeDriver: true,
}).start(() => {
setStack(stack => {
animatedValue.setValue(0);
if (stack.length > 1) {
return stack.slice(0, stack.length - 1);
}
return stack;
});
setActionHistory('POP');
});
}
useEffect(() => {
console.log('scene >>>', stack.slice(0, stack.length - 1));
console.log('last Action ===', lastAction);
if (lastAction === 'PUSH') {
animatedValue.setValue(width);
Animated.timing(animatedValue, {
toValue: 0,
duration: 250,
useNativeDriver: true,
}).start();
} else {
console.log('was pop')
}
}, [animatedValue, stack, lastAction]);
return (
<View style={styles.container}>
{stack.map((scene, index) => {
let CurrentScene = scene.component;
let sceneStyles = [styles.scene];
if (index === stack.length - 1 && index > 0) {
sceneStyles.push({
transform: [{translateX: animatedValue}],
});
}
return (
<Animated.View style={sceneStyles} key={scene.key}>
<CurrentScene navigator={{push, pop}} />
</Animated.View>
);
})}
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'row',
},
scene: {
...StyleSheet.absoluteFillObject,
flex: 1,
},
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment