react-native/Libraries/CustomComponents/Navigator/Navigation/NavigationRouteStack.js

257 lines
6.2 KiB
JavaScript
Raw Normal View History

/**
* Copyright 2004-present Facebook. All Rights Reserved.
*
* @providesModule NavigationRouteStack
[Navigator]: Add a method `keyOf` to NavigationRouteStack. 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>; } } ```
2015-07-29 23:42:46 +00:00
* @flow
*/
'use strict';
var immutable = require('immutable');
var invariant = require('invariant');
[Navigator]: Add a method `keyOf` to NavigationRouteStack. 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>; } } ```
2015-07-29 23:42:46 +00:00
type IterationCallback = (route: any, index: number, key: string) => void;
var {List, Set} = immutable;
[Navigator]: Add a method `keyOf` to NavigationRouteStack. 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>; } } ```
2015-07-29 23:42:46 +00:00
function isRouteEmpty(route: any): boolean {
return (route === undefined || route === null || route === '') || false;
}
var _nextID = 0;
class RouteNode {
key: string;
value: any;
constructor(route: any) {
// Key value gets bigger incrementally. Developer can compare the
// keys of two routes then know which route is added to the stack
// earlier.
this.key = String(_nextID++);
this.value = route;
}
}
var StackDiffRecord = immutable.Record({
key: null,
route: null,
index: null,
});
/**
[Navigator]: Add a method `keyOf` to NavigationRouteStack. 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>; } } ```
2015-07-29 23:42:46 +00:00
* The immutable route stack.
*/
class RouteStack {
_index: number;
[Navigator]: Add a method `keyOf` to NavigationRouteStack. 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>; } } ```
2015-07-29 23:42:46 +00:00
_routeNodes: List<RouteNode>;
[Navigator]: Add a method `keyOf` to NavigationRouteStack. 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>; } } ```
2015-07-29 23:42:46 +00:00
constructor(index: number, routeNodes: List<RouteNode>) {
invariant(
[Navigator]: Add a method `keyOf` to NavigationRouteStack. 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>; } } ```
2015-07-29 23:42:46 +00:00
routeNodes.size > 0,
'size must not be empty'
);
invariant(
[Navigator]: Add a method `keyOf` to NavigationRouteStack. 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>; } } ```
2015-07-29 23:42:46 +00:00
index > -1 && index <= routeNodes.size - 1,
'index out of bound'
);
[Navigator]: Add a method `keyOf` to NavigationRouteStack. 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>; } } ```
2015-07-29 23:42:46 +00:00
this._routeNodes = routeNodes;
this._index = index;
}
[Navigator]: Add a method `keyOf` to NavigationRouteStack. 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>; } } ```
2015-07-29 23:42:46 +00:00
/* $FlowFixMe - get/set properties not yet supported */
get size(): number {
[Navigator]: Add a method `keyOf` to NavigationRouteStack. 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>; } } ```
2015-07-29 23:42:46 +00:00
return this._routeNodes.size;
}
[Navigator]: Add a method `keyOf` to NavigationRouteStack. 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>; } } ```
2015-07-29 23:42:46 +00:00
/* $FlowFixMe - get/set properties not yet supported */
get index(): number {
return this._index;
}
[Navigator]: Add a method `keyOf` to NavigationRouteStack. 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>; } } ```
2015-07-29 23:42:46 +00:00
toArray(): Array<any> {
var result = [];
var ii = 0;
var nodes = this._routeNodes;
while (ii < nodes.size) {
result.push(nodes.get(ii).value);
ii++;
}
return result;
}
get(index: number): any {
[Navigator]: Add a method `keyOf` to NavigationRouteStack. 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>; } } ```
2015-07-29 23:42:46 +00:00
if (index < 0 || index > this._routeNodes.size - 1) {
return null;
}
return this._routeNodes.get(index).value;
}
/**
* Returns the key associated with the route.
* When a route is added to a stack, the stack creates a key for this route.
* The key will persist until the initial stack and its derived stack
* no longer contains this route.
*/
keyOf(route: any): ?string {
if (isRouteEmpty(route)) {
return null;
}
[Navigator]: Add a method `keyOf` to NavigationRouteStack. 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>; } } ```
2015-07-29 23:42:46 +00:00
var index = this.indexOf(route);
return index > -1 ?
this._routeNodes.get(index).key :
null;
}
indexOf(route: any): number {
[Navigator]: Add a method `keyOf` to NavigationRouteStack. 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>; } } ```
2015-07-29 23:42:46 +00:00
if (isRouteEmpty(route)) {
return -1;
}
var finder = (node) => {
return (node: RouteNode).value === route;
};
return this._routeNodes.findIndex(finder, this);
}
slice(begin: ?number, end: ?number): RouteStack {
[Navigator]: Add a method `keyOf` to NavigationRouteStack. 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>; } } ```
2015-07-29 23:42:46 +00:00
var routeNodes = this._routeNodes.slice(begin, end);
var index = Math.min(this._index, routeNodes.size - 1);
return this._update(index, routeNodes);
}
/**
* Returns a new stack with the provided route appended,
* starting at this stack size.
*/
push(route: any): RouteStack {
[Navigator]: Add a method `keyOf` to NavigationRouteStack. 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>; } } ```
2015-07-29 23:42:46 +00:00
invariant(
[Navigator]: Add a method `keyOf` to NavigationRouteStack. 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>; } } ```
2015-07-29 23:42:46 +00:00
!isRouteEmpty(route),
'Must supply route to push'
);
[Navigator]: Add a method `keyOf` to NavigationRouteStack. 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>; } } ```
2015-07-29 23:42:46 +00:00
invariant(this._routeNodes.indexOf(route) === -1, 'route must be unique');
// When pushing, removes the rest of the routes past the current index.
[Navigator]: Add a method `keyOf` to NavigationRouteStack. 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>; } } ```
2015-07-29 23:42:46 +00:00
var routeNodes = this._routeNodes.withMutations((list: List) => {
list.slice(0, this._index + 1).push(new RouteNode(route));
});
[Navigator]: Add a method `keyOf` to NavigationRouteStack. 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>; } } ```
2015-07-29 23:42:46 +00:00
return this._update(routeNodes.size - 1, routeNodes);
}
/**
* Returns a new stack a size ones less than this stack,
* excluding the last index in this stack.
*/
pop(): RouteStack {
[Navigator]: Add a method `keyOf` to NavigationRouteStack. 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>; } } ```
2015-07-29 23:42:46 +00:00
invariant(this._routeNodes.size > 1, 'shoud not pop routeNodes stack to empty');
// When popping, removes the rest of the routes past the current index.
[Navigator]: Add a method `keyOf` to NavigationRouteStack. 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>; } } ```
2015-07-29 23:42:46 +00:00
var routeNodes = this._routeNodes.slice(0, this._index);
return this._update(routeNodes.size - 1, routeNodes);
}
jumpToIndex(index: number): RouteStack {
invariant(
[Navigator]: Add a method `keyOf` to NavigationRouteStack. 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>; } } ```
2015-07-29 23:42:46 +00:00
index > -1 && index < this._routeNodes.size,
'index out of bound'
);
[Navigator]: Add a method `keyOf` to NavigationRouteStack. 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>; } } ```
2015-07-29 23:42:46 +00:00
return this._update(index, this._routeNodes);
}
/**
* Replace a route in the navigation stack.
*
* `index` specifies the route in the stack that should be replaced.
* If it's negative, it counts from the back.
*/
replaceAtIndex(index: number, route: any): RouteStack {
invariant(
[Navigator]: Add a method `keyOf` to NavigationRouteStack. 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>; } } ```
2015-07-29 23:42:46 +00:00
!isRouteEmpty(route),
'Must supply route to replace'
);
if (this.get(index) === route) {
return this;
}
[Navigator]: Add a method `keyOf` to NavigationRouteStack. 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>; } } ```
2015-07-29 23:42:46 +00:00
invariant(this.indexOf(route) === -1, 'route must be unique');
if (index < 0) {
[Navigator]: Add a method `keyOf` to NavigationRouteStack. 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>; } } ```
2015-07-29 23:42:46 +00:00
index += this._routeNodes.size;
}
invariant(
[Navigator]: Add a method `keyOf` to NavigationRouteStack. 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>; } } ```
2015-07-29 23:42:46 +00:00
index > -1 && index < this._routeNodes.size,
'index out of bound'
);
[Navigator]: Add a method `keyOf` to NavigationRouteStack. 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>; } } ```
2015-07-29 23:42:46 +00:00
var routeNodes = this._routeNodes.set(index, new RouteNode(route));
return this._update(index, routeNodes);
}
// Iterations
forEach(callback: IterationCallback, context: ?Object): void {
var ii = 0;
var nodes = this._routeNodes;
while (ii < nodes.size) {
var node = nodes.get(ii);
callback(node.value, ii, node.key);
ii++;
}
}
/**
* Returns a Set excluding any routes contained within the stack given.
*/
subtract(stack: RouteStack): Set<StackDiffRecord> {
var items = [];
this._routeNodes.forEach((node: RouteNode, index: number) => {
if (!stack._routeNodes.contains(node)) {
items.push(
new StackDiffRecord({
route: node.value,
index: index,
key: node.key,
})
);
}
});
return new Set(items);
}
[Navigator]: Add a method `keyOf` to NavigationRouteStack. 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>; } } ```
2015-07-29 23:42:46 +00:00
_update(index: number, routeNodes: List): RouteStack {
if (this._index === index && this._routeNodes === routeNodes) {
return this;
}
[Navigator]: Add a method `keyOf` to NavigationRouteStack. 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>; } } ```
2015-07-29 23:42:46 +00:00
return new RouteStack(index, routeNodes);
}
}
/**
* The first class data structure for NavigationContext to manage the navigation
* stack of routes.
*/
class NavigationRouteStack extends RouteStack {
[Navigator]: Add a method `keyOf` to NavigationRouteStack. 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>; } } ```
2015-07-29 23:42:46 +00:00
constructor(index: number, routeNodes: Array<any>) {
// For now, `RouteStack` internally, uses an immutable `List` to keep
[Navigator]: Add a method `keyOf` to NavigationRouteStack. 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>; } } ```
2015-07-29 23:42:46 +00:00
// track of routeNodes. Since using `List` is really just the implementation
// detail, we don't want to accept `routeNodes` as `list` from constructor
// for developer.
[Navigator]: Add a method `keyOf` to NavigationRouteStack. 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>; } } ```
2015-07-29 23:42:46 +00:00
var nodes = routeNodes.map((route) => {
invariant(!isRouteEmpty(route), 'route must not be mepty');
return new RouteNode(route);
});
super(index, new List(nodes));
}
}
module.exports = NavigationRouteStack;