1import React, { Component } from 'react'; 2import { StyleSheet, Button, View, TextInput } from 'react-native'; 3import { Screen, ScreenStack } from 'react-native-screens'; 4 5type StackProps = { 6 renderScreen: (key: string) => JSX.Element; 7}; 8 9type StackState = { 10 stack: string[]; 11 transitioning: number; 12}; 13 14const COLORS = ['azure', 'pink', 'cyan']; 15 16export class Stack extends Component<StackProps, StackState> { 17 state = { 18 stack: ['azure'], 19 transitioning: 0, 20 }; 21 22 push(key: string) { 23 const { stack } = this.state; 24 this.setState({ stack: [...stack, key], transitioning: 1 }); 25 } 26 27 pop() { 28 const { stack } = this.state; 29 this.setState({ transitioning: 0, stack: stack.slice(0, -1) }); 30 } 31 32 remove(index: number) { 33 const { stack } = this.state; 34 this.setState({ stack: stack.filter((v, idx) => idx !== index) }); 35 } 36 37 removeByKey(key: string) { 38 const { stack } = this.state; 39 this.setState({ stack: stack.filter((v) => key !== v) }); 40 } 41 42 renderScreen = (key: string) => { 43 return ( 44 <Screen 45 style={StyleSheet.absoluteFill} 46 key={key} 47 stackAnimation="fade" 48 stackPresentation="push" 49 onDismissed={() => this.removeByKey(key)}> 50 {this.props.renderScreen(key)} 51 </Screen> 52 ); 53 }; 54 55 render() { 56 const screens = this.state.stack.map(this.renderScreen); 57 return <ScreenStack style={styles.container}>{screens}</ScreenStack>; 58 } 59} 60 61class App extends Component { 62 stackRef = React.createRef<Stack>(); 63 64 renderScreen = (key: string) => { 65 const index = COLORS.indexOf(key); 66 const color = key; 67 const pop = index > 0 ? () => this.stackRef.current?.pop() : null; 68 const push = index < 2 ? () => this.stackRef.current?.push(COLORS[index + 1]) : null; 69 const remove = index > 1 ? () => this.stackRef.current?.remove(1) : null; 70 71 return ( 72 <View 73 style={{ 74 flex: 1, 75 backgroundColor: color, 76 alignItems: 'center', 77 justifyContent: 'center', 78 // margin: index * 40, 79 }}> 80 <View 81 style={{ 82 position: 'absolute', 83 top: 110, 84 left: 0, 85 width: 80, 86 height: 80, 87 backgroundColor: 'black', 88 }} 89 /> 90 {pop && <Button title="Pop" onPress={pop} />} 91 {push && <Button title="Push" onPress={push} />} 92 {remove && <Button title="Remove middle screen" onPress={remove} />} 93 <TextInput placeholder="Hello" style={styles.textInput} /> 94 <View style={{ height: 100, backgroundColor: 'red', width: '70%' }} /> 95 </View> 96 ); 97 }; 98 99 render() { 100 return <Stack ref={this.stackRef} renderScreen={this.renderScreen} />; 101 } 102} 103 104const styles = StyleSheet.create({ 105 container: { 106 flex: 1, 107 justifyContent: 'center', 108 alignItems: 'center', 109 backgroundColor: '#F5FCFF', 110 }, 111 textInput: { 112 backgroundColor: 'white', 113 borderWidth: 1, 114 padding: 10, 115 marginHorizontal: 20, 116 alignSelf: 'stretch', 117 borderColor: 'black', 118 }, 119}); 120 121export default App; 122