|
1 |
| -import React, { useState, useEffect } from 'react'; |
| 1 | +import React, { useState, useEffect, useCallback } from 'react'; |
2 | 2 | import {
|
3 | 3 | Animated,
|
4 | 4 | ScrollView,
|
@@ -57,63 +57,76 @@ const MaterialTabs: React.FC<Props> = ({
|
57 | 57 | const scrollView = React.createRef<ScrollView>();
|
58 | 58 | const bar = React.createRef<View>();
|
59 | 59 |
|
60 |
| - useEffect(() => { |
61 |
| - bar.current && |
62 |
| - bar.current.measure((_, b, width) => { |
63 |
| - getTabWidth(width); |
64 |
| - }); |
| 60 | + const getTabWidth = useCallback( |
| 61 | + (width: number) => { |
| 62 | + if (!scrollable) { |
| 63 | + setTabWidth(width / items.length); |
| 64 | + } |
65 | 65 |
|
66 |
| - selectTab(); |
67 |
| - // eslint-disable-next-line react-hooks/exhaustive-deps |
68 |
| - }, [items, barWidth]); |
| 66 | + setBarWidth(width); |
| 67 | + }, |
| 68 | + [items.length, scrollable] |
| 69 | + ); |
69 | 70 |
|
70 |
| - const getAnimateValues = () => { |
71 |
| - const scrollValue = !scrollable ? tabWidth : barWidth * 0.4; |
| 71 | + useEffect(() => { |
| 72 | + const getAnimateValues = () => { |
| 73 | + const scrollValue = !scrollable ? tabWidth : barWidth * 0.4; |
72 | 74 |
|
73 |
| - const indicator = I18nManager.isRTL |
74 |
| - ? -selectedIndex * scrollValue |
75 |
| - : selectedIndex * scrollValue; |
| 75 | + const indicator = I18nManager.isRTL |
| 76 | + ? -selectedIndex * scrollValue |
| 77 | + : selectedIndex * scrollValue; |
| 78 | + |
| 79 | + // All props for fixed tabs are the same |
| 80 | + if (!scrollable) { |
| 81 | + return { |
| 82 | + indicatorPosition: indicator, |
| 83 | + scrollPosition: 0, |
| 84 | + }; |
| 85 | + } |
76 | 86 |
|
77 |
| - // All props for fixed tabs are the same |
78 |
| - if (!scrollable) { |
79 | 87 | return {
|
80 | 88 | indicatorPosition: indicator,
|
81 |
| - scrollPosition: 0, |
| 89 | + scrollPosition: I18nManager.isRTL |
| 90 | + ? scrollValue * 0.25 + |
| 91 | + scrollValue * (items.length - selectedIndex - 2) |
| 92 | + : scrollValue * 0.25 + scrollValue * (selectedIndex - 1), |
82 | 93 | };
|
83 |
| - } |
84 |
| - |
85 |
| - return { |
86 |
| - indicatorPosition: indicator, |
87 |
| - scrollPosition: I18nManager.isRTL |
88 |
| - ? scrollValue * 0.25 + scrollValue * (items.length - selectedIndex - 2) |
89 |
| - : scrollValue * 0.25 + scrollValue * (selectedIndex - 1), |
90 | 94 | };
|
91 |
| - }; |
92 | 95 |
|
93 |
| - const getTabWidth = (width: number) => { |
94 |
| - if (!scrollable) { |
95 |
| - setTabWidth(width / items.length); |
96 |
| - } |
97 |
| - |
98 |
| - setBarWidth(width); |
99 |
| - }; |
100 |
| - |
101 |
| - const selectTab = () => { |
102 |
| - const values = getAnimateValues(); |
103 |
| - |
104 |
| - Animated.spring(indicatorPosition, { |
105 |
| - toValue: values.indicatorPosition, |
106 |
| - tension: 300, |
107 |
| - friction: 20, |
108 |
| - useNativeDriver: true, |
109 |
| - }).start(); |
| 96 | + const selectTab = () => { |
| 97 | + const values = getAnimateValues(); |
| 98 | + |
| 99 | + Animated.spring(indicatorPosition, { |
| 100 | + toValue: values.indicatorPosition, |
| 101 | + tension: 300, |
| 102 | + friction: 20, |
| 103 | + useNativeDriver: true, |
| 104 | + }).start(); |
| 105 | + |
| 106 | + if (scrollView.current) { |
| 107 | + scrollView.current.scrollTo({ |
| 108 | + x: values.scrollPosition, |
| 109 | + }); |
| 110 | + } |
| 111 | + }; |
110 | 112 |
|
111 |
| - if (scrollView.current) { |
112 |
| - scrollView.current.scrollTo({ |
113 |
| - x: values.scrollPosition, |
| 113 | + bar.current && |
| 114 | + bar.current.measure((_, b, width) => { |
| 115 | + getTabWidth(width); |
114 | 116 | });
|
115 |
| - } |
116 |
| - }; |
| 117 | + |
| 118 | + selectTab(); |
| 119 | + }, [ |
| 120 | + bar, |
| 121 | + barWidth, |
| 122 | + getTabWidth, |
| 123 | + indicatorPosition, |
| 124 | + items.length, |
| 125 | + scrollView, |
| 126 | + scrollable, |
| 127 | + selectedIndex, |
| 128 | + tabWidth, |
| 129 | + ]); |
117 | 130 |
|
118 | 131 | return (
|
119 | 132 | items && (
|
|
0 commit comments