1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | 3x 14x 14x 14x 42x 65x 3x 50x 3x 32x 32x 45x 32x 32x 3x 3x 26x 54x 127x 54x 73x 54x 32x 19x 54x 54x | /* @flow */ import React from 'react' import { matchPath } from 'react-router' import type { Location, MatchPathOptions } from 'react-router' import type { Route } from './TypeDefinitions' // Test if current stack item should be updated export const shouldUpdate = ( currentItem: MatchPathOptions, nextItem: MatchPathOptions, currentLocation: Location, nextLocation: Location, ): boolean => { // Get entries and matchs const matchCurrentRoute = matchPath(currentLocation.pathname, currentItem) const matchNextRoute = matchPath(nextLocation.pathname, nextItem) return ( // Test if pathames are different currentLocation.pathname !== nextLocation.pathname && // case 1) basic pathname (currentItem.path !== nextItem.path || // case 2) pathname with query params // ex: with same path article/:id, // pathname article/2 !== article/3 (matchCurrentRoute !== null && matchNextRoute !== null && Object.keys(matchCurrentRoute.params).length !== 0 && Object.keys(matchNextRoute.params).length !== 0 && currentLocation.pathname !== nextLocation.pathname)) ) } // Get stack item from a specific route export const get = <Item>(items: Array<Item>, route: Route): Item => ({ ...route, ...items.find(item => { return item && item.key && route.routeName === item.key }), }) // Generate unique key export const createKey = (route: Route): string => { return `${route.key}@@${Math.random() .toString(10) .slice(1)}` } // Get current route from a specific history location export const getRoute = (stack: Array<Object>, location: Location): ?Route => { const { pathname } = location const item = stack.find(stackItem => { return matchPath(pathname, stackItem) }) Iif (!item || !item.key) return null return { key: createKey(item), routeName: item.key, match: matchPath(pathname, item), } } // Render a subview with props export const renderSubView = (render: Function, additionalProps?: * = {}) => ( ownProps: *, ): React$Element<*> => { const props = { ...additionalProps, ...ownProps } const { cards, tabs, scene, route, navigationState: { routes, index }, } = props const item = { ...props, ...get(cards || tabs, (scene && scene.route) || route || routes[index]), } return render( Object.keys(item).reduce((acc, key) => { const value = item[key] if (value === undefined) return acc return { ...acc, [key]: value } }, {}), props, ) } // Build stack with React elements export const build = <Item>( children: Array<React$Element<Item>>, oldBuild?: Array<Item>, ): Array<Item> => { return React.Children.toArray(children).reduce((stack, child, index) => { const item = Object.keys(child.props).reduce((props, key) => { if (key === 'path') { return { ...props, key: child.props[key], } } else if ( key === 'render' || key === 'component' || key === 'children' ) { return { ...props, [key]: oldBuild && oldBuild[index] // $FlowFixMe ? oldBuild[index][key] : () => React.cloneElement(child), } } return props }, child.props) Iif (!item.key) return stack return [...stack, item] }, []) } |