Skip to content

Commit 21258a5

Browse files
committed
fix: fix scrollYOffset when SSR
1 parent 32a464a commit 21258a5

File tree

1 file changed

+39
-33
lines changed

1 file changed

+39
-33
lines changed

src/components/StickySidebar/StickyResponsiveSidebar.tsx

Lines changed: 39 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ export interface StickySidebarProps {
1919
menu: MenuStore;
2020
}
2121

22+
export interface StickySidebarState {
23+
offsetTop?: string;
24+
}
25+
2226
const stickyfill = Stickyfill && Stickyfill();
2327

2428
const StyledStickySidebar = styled.div<{ open?: boolean }>`
@@ -77,13 +81,26 @@ const FloatingButton = styled.div`
7781
`;
7882

7983
@observer
80-
export class StickyResponsiveSidebar extends React.Component<StickySidebarProps> {
84+
export class StickyResponsiveSidebar extends React.Component<
85+
StickySidebarProps,
86+
StickySidebarState
87+
> {
88+
static contextType = OptionsContext;
89+
context!: React.ContextType<typeof OptionsContext>;
90+
state: StickySidebarState = {};
91+
8192
stickyElement: Element;
8293

8394
componentDidMount() {
8495
if (stickyfill) {
8596
stickyfill.add(this.stickyElement);
8697
}
98+
99+
// rerender when hydrating from SSR
100+
// see https://github.com/facebook/react/issues/8017#issuecomment-256351955
101+
this.setState({
102+
offsetTop: this.getScrollYOffset(this.context),
103+
});
87104
}
88105

89106
componentWillUnmount() {
@@ -92,7 +109,7 @@ export class StickyResponsiveSidebar extends React.Component<StickySidebarProps>
92109
}
93110
}
94111

95-
getScrollYOffset(options) {
112+
getScrollYOffset(options: RedocNormalizedOptions) {
96113
let top;
97114
if (this.props.scrollYOffset !== undefined) {
98115
top = RedocNormalizedOptions.normalizeScrollYOffset(this.props.scrollYOffset)();
@@ -105,43 +122,32 @@ export class StickyResponsiveSidebar extends React.Component<StickySidebarProps>
105122
render() {
106123
const open = this.props.menu.sideBarOpened;
107124

108-
const style = options => {
109-
const top = this.getScrollYOffset(options);
110-
return {
111-
top,
112-
height: `calc(100vh - ${top})`,
113-
};
114-
};
125+
const top = this.state.offsetTop || this.getScrollYOffset(this.context);
115126

116127
return (
117-
<OptionsContext.Consumer>
118-
{options => (
119-
<>
120-
<StyledStickySidebar
121-
open={open}
122-
className={this.props.className}
123-
style={style(options)}
124-
// tslint:disable-next-line
125-
ref={el => {
126-
this.stickyElement = el as any;
127-
}}
128-
>
129-
{this.props.children}
130-
</StyledStickySidebar>
131-
<FloatingButton onClick={this.toggleNavMenu}>
132-
<AnimatedChevronButton open={open} />
133-
</FloatingButton>
134-
</>
135-
)}
136-
</OptionsContext.Consumer>
128+
<>
129+
<StyledStickySidebar
130+
open={open}
131+
className={this.props.className}
132+
style={{
133+
top,
134+
height: `calc(100vh - ${top})`,
135+
}}
136+
// tslint:disable-next-line
137+
ref={el => {
138+
this.stickyElement = el as any;
139+
}}
140+
>
141+
{this.props.children}
142+
</StyledStickySidebar>
143+
<FloatingButton onClick={this.toggleNavMenu}>
144+
<AnimatedChevronButton open={open} />
145+
</FloatingButton>
146+
</>
137147
);
138148
}
139149

140150
private toggleNavMenu = () => {
141151
this.props.menu.toggleSidebar();
142152
};
143-
144-
// private closeNavMenu = () => {
145-
// this.setState({ open: false });
146-
// };
147153
}

0 commit comments

Comments
 (0)