mirror of
https://github.com/status-im/react-native.git
synced 2025-01-09 17:15:54 +00:00
4b16e4d550
Summary: # Summary Add a method `keyOf` to NavigationRouteStack. The method `keyOf` returns a key that is associated with the route. The a route is added to a stack, the stack creats an unique key for it and will keep the key for the route until the route is rmeoved from the stack. The stack also passes the keys to its derived stack (the new stack created by the mutation API such as `push`, `pop`...etc). The key for the route persists until the initial stack and its derived stack no longer contains this route. # Why Do We Need This? Navigator has needs to use an unique key to manage the scenes rendered. The problem is that `route` itself isn't a very reliable thing to be used as the key. Consider this example: ``` // `scene_1` animates into the viewport. navigator.push('scene_1'); setTimeout(() => { // `scene_1` animates off the viewport. navigator.pop(); }, 100); setTimeout(() => { // Should we bring in a new scene or bring back the one that was previously popped? navigator.push('scene_1'); }, 200); ``` Because we currently use `route` itself as a key for the scene, we'd have to block a route until its scene is completely off the components tree even the route itself is no longer in the stack otherwise we'd see strange animation of jumping scenes. # What's Next We're hoping that we can build pure reactive view for NavigationRouteStack easily. The naive implementation of NavigationRouteStackView may look like this: ``` class NavigationRouteStackView { constructor() { this.state = { staleScenes: {}, }; } componentWillReceiveProps(nextProps) { if (nextProps.stack !== this.props.stack) { var stale; var staleScenes = {...this.state.staleScenes}; this.props.stack.forEach((route, index, key) => { if (nextProps.stack.keyOf(route) !== key) { stale = true; staleScenes[key] = {route, index, key, stale}; } }); if (stale) { this.setState({ staleScenes, }); } } } render() { var scenes = []; this.props.stack.forEach((route, index, key) => { scenes.push({route, index, key}); }); Object.keys(this.state.staleScenes).forEach(key => { scenes.push(this.state.staleScenes[key]); }); scenes.sort(stableSortByIndex); return <View>{scenes.map(renderScene)}</View>; } } ```