@@ -29,6 +29,8 @@ export interface SwitchState {
2929 width : number ;
3030 height : number ;
3131 } ;
32+ control : 'props' | 'state' ;
33+ animatedStart : ( checked : boolean ) => void ;
3234}
3335
3436export default class Switch extends React . Component < SwitchProps , SwitchState > {
@@ -41,70 +43,69 @@ export default class Switch extends React.Component<SwitchProps, SwitchState> {
4143 color : '#4DD964' ,
4244 onValueChange : ( ) => { } ,
4345 } ;
46+ private animatedStart : ( checked : boolean ) => void ;
4447 constructor ( props : SwitchProps ) {
4548 super ( props ) ;
46- this . state = {
47- checked : ! ! this . props . checked ,
48- containerSize : { width : 0 , height : 0 } ,
49- borderValue : new Animated . Value ( 0 ) ,
50- translateXValue : new Animated . Value ( 2 ) ,
51- bgOpacity : new Animated . Value ( props . value ? 1 : 0 ) ,
52- } ;
53- this . animatedStart ( ! ! this . props . checked ) ;
54- }
55- UNSAFE_componentWillReceiveProps ( nextProps : SwitchProps ) {
56- if ( this . props . checked !== nextProps . checked ) {
57- this . setState ( { checked : ! ! nextProps . checked } , ( ) => {
58- this . animatedStart ( ! ! nextProps . checked ) ;
59- } ) ;
60- }
61- }
62- animatedStart ( checked : boolean ) {
63- if ( checked ) {
49+ this . animatedStart = ( checked : boolean ) => {
50+ const obj = {
51+ height : this . height ,
52+ number : 1 ,
53+ translateXValue : this . translateXValue ,
54+ } ;
55+ if ( ! checked ) {
56+ obj . height = 2 ;
57+ obj . number = 0 ;
58+ obj . translateXValue = 2 ;
59+ }
6460 Animated . parallel ( [
6561 Animated . sequence ( [
6662 Animated . spring ( this . state . borderValue , {
67- toValue : this . height ,
68- overshootClamping : true ,
69- useNativeDriver : false ,
70- } ) ,
71- Animated . spring ( this . state . bgOpacity , {
72- toValue : 1 ,
63+ toValue : obj . height ,
7364 overshootClamping : true ,
7465 useNativeDriver : false ,
7566 } ) ,
76- ] ) ,
77- Animated . spring ( this . state . translateXValue , {
78- toValue : this . translateXValue ,
79- overshootClamping : true ,
80- useNativeDriver : false ,
81- } ) ,
82- ] ) . start ( ) ;
83- } else {
84- Animated . parallel ( [
85- Animated . sequence ( [
8667 Animated . spring ( this . state . bgOpacity , {
87- toValue : 0 ,
88- overshootClamping : true ,
89- useNativeDriver : false ,
90- } ) ,
91- Animated . spring ( this . state . borderValue , {
92- toValue : 2 ,
68+ toValue : obj . number ,
9369 overshootClamping : true ,
9470 useNativeDriver : false ,
9571 } ) ,
9672 ] ) ,
9773 Animated . spring ( this . state . translateXValue , {
98- toValue : 2 ,
74+ toValue : obj . translateXValue ,
9975 overshootClamping : true ,
10076 useNativeDriver : false ,
10177 } ) ,
10278 ] ) . start ( ) ;
79+ } ;
80+ this . state = {
81+ checked : ! ! this . props . checked ,
82+ containerSize : { width : 0 , height : 0 } ,
83+ borderValue : new Animated . Value ( 0 ) ,
84+ translateXValue : new Animated . Value ( 2 ) ,
85+ bgOpacity : new Animated . Value ( props . value ? 1 : 0 ) ,
86+ control : 'state' ,
87+ animatedStart : this . animatedStart ,
88+ } ;
89+ this . animatedStart ( ! ! this . props . checked ) ;
90+ }
91+ static getDerivedStateFromProps ( props : SwitchProps , state : SwitchState ) {
92+ if ( state . control === 'state' ) {
93+ return {
94+ control : 'props' ,
95+ } ;
96+ }
97+ if ( props . checked !== state . checked ) {
98+ state . animatedStart ( ! ! props . checked ) ;
99+ return {
100+ checked : ! ! props . checked ,
101+ control : 'props' ,
102+ } ;
103103 }
104+ return null ;
104105 }
105106 onPress = ( ) => {
106107 const checked = ! this . state . checked ;
107- this . setState ( { checked } , ( ) => {
108+ this . setState ( { checked, control : 'state' } , ( ) => {
108109 this . animatedStart ( checked ) ;
109110 this . props . onValueChange ! ( checked ) ;
110111 } ) ;
@@ -120,7 +121,7 @@ export default class Switch extends React.Component<SwitchProps, SwitchState> {
120121 const state = { containerSize : size } ;
121122 this . translateXValue = layoutWidth - 2 - width ;
122123 translateXValue . setValue ( checked ? layoutWidth - 2 - width : 2 ) ;
123- this . setState ( { ...state } , ( ) => {
124+ this . setState ( { ...state , control : 'state' } , ( ) => {
124125 this . animatedStart ( ! ! this . props . checked ) ;
125126 } ) ;
126127 } ;
0 commit comments