33 * @module components
44 */ /** */
55import * as React from 'react' ;
6- import { Component , cloneElement , ValidationMap } from 'react' ;
6+ import { Component , cloneElement , ValidationMap } from 'react' ;
77import * as PropTypes from 'prop-types' ;
88import * as _classNames from 'classnames' ;
99
10- import { UIRouterReact , UISref } from '../index' ;
11- import { UIViewAddress } from './UIView' ;
10+ import { UIRouterReact , UISref } from '../index' ;
11+ import { UIViewAddress } from './UIView' ;
1212
1313let classNames = _classNames ;
1414
@@ -19,15 +19,15 @@ export interface UISrefActiveProps {
1919}
2020
2121export interface UISrefActiveState {
22- state : { name : string ; [ key : string ] : any } ;
22+ state : { name : string ; [ key : string ] : any } ;
2323 params : Object ;
2424 hash : string ;
2525}
2626
2727export class UISrefActive extends Component < UISrefActiveProps , any > {
2828 // keep track of states to watch and their activeClasses
2929 states : Array < UISrefActiveState > = [ ] ;
30- activeClasses : { [ key : string ] : string } = { } ;
30+ activeClasses : { [ key : string ] : string } = { } ;
3131
3232 // deregister the callback for state changed when unmounted
3333 deregister : Function ;
@@ -46,6 +46,10 @@ export class UISrefActive extends Component<UISrefActiveProps, any> {
4646 parentUiSrefActiveAddStateInfo : PropTypes . func ,
4747 } ;
4848
49+ state = {
50+ activeClasses : '' ,
51+ } ;
52+
4953 getChildContext ( ) {
5054 return {
5155 parentUiSrefActiveAddStateInfo : this . addStateInfo ,
@@ -62,7 +66,7 @@ export class UISrefActive extends Component<UISrefActiveProps, any> {
6266 // register callback for state change
6367 this . deregister = this . context [
6468 'router'
65- ] . transitionService . onSuccess ( { } , ( ) => this . forceUpdate ( ) ) ;
69+ ] . transitionService . onSuccess ( { } , ( ) => this . updateActiveClasses ( ) ) ;
6670 }
6771
6872 componentWillUnmount ( ) {
@@ -72,19 +76,19 @@ export class UISrefActive extends Component<UISrefActiveProps, any> {
7276 addStateInfo = ( stateName , stateParams ) => {
7377 const activeClass = this . props . class ;
7478 let deregister = this . addState ( stateName , stateParams , activeClass ) ;
75- this . forceUpdate ( ) ;
79+ this . updateActiveClasses ( ) ;
7680 return deregister ;
7781 } ;
7882
7983 addState = ( stateName , stateParams , activeClass ) => {
80- const { stateService} = this . context [ 'router' ] ;
84+ const { stateService } = this . context [ 'router' ] ;
8185 let parent = this . context [ 'parentUIViewAddress' ] ;
8286 let stateContext =
8387 ( parent && parent . context ) || this . context [ 'router' ] . stateRegistry . root ( ) ;
8488 let state = stateService . get ( stateName , stateContext ) ;
8589 let stateHash = this . createStateHash ( stateName , stateParams ) ;
8690 let stateInfo = {
87- state : state || { name : stateName } ,
91+ state : state || { name : stateName } ,
8892 params : stateParams ,
8993 hash : stateHash ,
9094 } ;
@@ -105,22 +109,32 @@ export class UISrefActive extends Component<UISrefActiveProps, any> {
105109 : state ;
106110 } ;
107111
108- getActiveClasses = ( ) => {
112+ getActiveClasses = ( ) : string => {
109113 let activeClasses = [ ] ;
110- let { stateService} = this . context [ 'router' ] ;
111- let { exact} = this . props ;
114+ let { stateService } = this . context [ 'router' ] ;
115+ let { exact } = this . props ;
112116 this . states . forEach ( s => {
113- let { state, params, hash} = s ;
117+ let { state, params, hash } = s ;
114118 if ( ! exact && stateService . includes ( state . name , params ) )
115119 activeClasses . push ( this . activeClasses [ hash ] ) ;
116120 if ( exact && stateService . is ( state . name , params ) )
117121 activeClasses . push ( this . activeClasses [ hash ] ) ;
118122 } ) ;
119- return activeClasses ;
123+ return classNames ( activeClasses ) ;
124+ } ;
125+
126+ updateActiveClasses = ( ) : void => {
127+ const { activeClasses } = this . state ;
128+ const newActiveClasses = this . getActiveClasses ( ) ;
129+ if ( activeClasses !== newActiveClasses ) {
130+ this . setState ( {
131+ activeClasses : this . getActiveClasses ( ) ,
132+ } ) ;
133+ }
120134 } ;
121135
122136 render ( ) {
123- let activeClasses = this . getActiveClasses ( ) ;
137+ const { activeClasses } = this . state ;
124138 return activeClasses . length > 0
125139 ? cloneElement (
126140 this . props . children ,
0 commit comments