Skip to content
This repository has been archived by the owner on Nov 27, 2022. It is now read-only.

Commit

Permalink
Revert "fix: move layout from state to class member (#915)"
Browse files Browse the repository at this point in the history
This reverts commit 8eedb61.

Reason: This breaks the indicator when tab bar is not scrollable. The indicator is always stuck in the initial position.
  • Loading branch information
satya164 committed Nov 17, 2019
1 parent 52f8713 commit d368c93
Showing 1 changed file with 23 additions and 26 deletions.
49 changes: 23 additions & 26 deletions src/TabBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export type Props<T extends Route> = SceneRendererProps & {
};

type State = {
layout: Layout;
tabWidths: { [key: string]: number };
};

Expand All @@ -85,23 +86,25 @@ export default class TabBar<T extends Route> extends React.Component<
};

state: State = {
layout: { width: 0, height: 0 },
tabWidths: {},
};

componentDidUpdate(prevProps: Props<T>, prevState: State) {
const { navigationState } = this.props;
const { tabWidths } = this.state;
const { layout, tabWidths } = this.state;

if (
prevProps.navigationState.routes.length !==
navigationState.routes.length ||
prevProps.navigationState.index !== navigationState.index ||
prevState.layout.width !== layout.width ||
prevState.tabWidths !== tabWidths
) {
if (
this.getFlattenedTabWidth(this.props.tabStyle) === 'auto' &&
!(
this.layout.width &&
layout.width &&
navigationState.routes.every(
r => typeof tabWidths[r.key] === 'number'
)
Expand All @@ -115,8 +118,6 @@ export default class TabBar<T extends Route> extends React.Component<
}
}

private layout: Layout = { width: 0, height: 0 };

// to store the layout.width of each tab
// when all onLayout's are fired, this would be set in state
private measuredTabWidths: { [key: string]: number } = {};
Expand Down Expand Up @@ -184,7 +185,7 @@ export default class TabBar<T extends Route> extends React.Component<
tabBarWidth - layoutWidth;

private getTabBarWidth = (props: Props<T>, state: State) => {
const { tabWidths } = state;
const { layout, tabWidths } = state;
const { scrollEnabled, tabStyle } = props;
const { routes } = props.navigationState;

Expand All @@ -193,7 +194,7 @@ export default class TabBar<T extends Route> extends React.Component<
acc +
this.getComputedTabWidth(
i,
this.layout,
layout,
routes,
scrollEnabled,
tabWidths,
Expand All @@ -208,7 +209,7 @@ export default class TabBar<T extends Route> extends React.Component<
state: State,
value: number
) => {
const { layout } = this;
const { layout } = state;
const tabBarWidth = this.getTabBarWidth(props, state);
const maxDistance = this.getMaxScrollDistance(tabBarWidth, layout.width);
const scrollValue = Math.max(Math.min(value, maxDistance), 0);
Expand All @@ -223,8 +224,7 @@ export default class TabBar<T extends Route> extends React.Component<
};

private getScrollAmount = (props: Props<T>, state: State, index: number) => {
const { tabWidths } = state;
const { layout } = this;
const { layout, tabWidths } = state;
const { scrollEnabled, tabStyle } = props;
const { routes } = props.navigationState;

Expand Down Expand Up @@ -264,20 +264,19 @@ export default class TabBar<T extends Route> extends React.Component<
private handleLayout = (e: LayoutChangeEvent) => {
const { height, width } = e.nativeEvent.layout;

// Decided not to place layout in state because
// onLayout is often called before applying changes
// (according to https://facebook.github.io/react-native/docs/view.html#onlayout)
// and new state (and related evaluation)
// can be called before actually applying new related which might lead
// to unexpected position of components.
// Furthermore, component gets updated anyway after changing orientation
// so having it stored as a class member is good enough and new values will
// be consider in a new render.
// Anyway, we call forceUpdate because handleLayout can
// be invoked not only as a result of orientation's change.
this.layout.height = height;
this.layout.width = width;
this.forceUpdate();
if (
this.state.layout.width === width &&
this.state.layout.height === height
) {
return;
}

this.setState({
layout: {
height,
width,
},
});
};

private getTranslateX = memoize(
Expand Down Expand Up @@ -317,9 +316,7 @@ export default class TabBar<T extends Route> extends React.Component<
style,
indicatorContainerStyle,
} = this.props;

const { tabWidths } = this.state;
const { layout } = this;
const { layout, tabWidths } = this.state;
const { routes } = navigationState;

const isWidthDynamic = this.getFlattenedTabWidth(tabStyle) === 'auto';
Expand Down

0 comments on commit d368c93

Please sign in to comment.