Skip to content

Commit 234e070

Browse files
alduzyja1ns
authored andcommitted
refactor: screen rewritten as functional component (software-mansion#2111)
## Description This PR intents to change Screen component into a functional component.
1 parent 0669aa6 commit 234e070

File tree

1 file changed

+27
-33
lines changed

1 file changed

+27
-33
lines changed

src/components/Screen.tsx

Lines changed: 27 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
/* eslint-disable @typescript-eslint/no-var-requires */
21
import React from 'react';
32
import { Animated, View, Platform } from 'react-native';
43

@@ -17,7 +16,7 @@ import ScreenNativeComponent from '../fabric/ScreenNativeComponent';
1716
import ModalScreenNativeComponent from '../fabric/ModalScreenNativeComponent';
1817

1918
export const NativeScreen: React.ComponentType<ScreenProps> =
20-
ScreenNativeComponent as any;
19+
ScreenNativeComponent as React.ComponentType<ScreenProps>;
2120
const AnimatedNativeScreen = Animated.createAnimatedComponent(NativeScreen);
2221
const AnimatedNativeModalScreen = Animated.createAnimatedComponent(
2322
ModalScreenNativeComponent as React.ComponentType<ScreenProps>
@@ -42,27 +41,25 @@ interface ViewConfig extends View {
4241
};
4342
}
4443

45-
export class InnerScreen extends React.Component<ScreenProps> {
46-
private ref: React.ElementRef<typeof View> | null = null;
47-
private closing = new Animated.Value(0);
48-
private progress = new Animated.Value(0);
49-
private goingForward = new Animated.Value(0);
44+
export const InnerScreen = React.forwardRef<View, ScreenProps>(
45+
function InnerScreen(props, ref) {
46+
const innerRef = React.useRef<ViewConfig | null>(null);
47+
React.useImperativeHandle(ref, () => innerRef.current!, []);
5048

51-
setNativeProps(props: ScreenProps): void {
52-
this.ref?.setNativeProps(props);
53-
}
49+
const setRef = (ref: ViewConfig) => {
50+
innerRef.current = ref;
51+
props.onComponentRef?.(ref);
52+
};
5453

55-
setRef = (ref: React.ElementRef<typeof View> | null): void => {
56-
this.ref = ref;
57-
this.props.onComponentRef?.(ref);
58-
};
54+
const closing = React.useRef(new Animated.Value(0)).current;
55+
const progress = React.useRef(new Animated.Value(0)).current;
56+
const goingForward = React.useRef(new Animated.Value(0)).current;
5957

60-
render() {
6158
const {
6259
enabled = screensEnabled(),
6360
freezeOnBlur = freezeEnabled(),
6461
...rest
65-
} = this.props;
62+
} = props;
6663

6764
// To maintain default behavior of formSheet stack presentation style and to have reasonable
6865
// defaults for new medium-detent iOS API we need to set defaults here
@@ -112,13 +109,13 @@ export class InnerScreen extends React.Component<ScreenProps> {
112109
...ref.viewConfig.validAttributes.style,
113110
display: false,
114111
};
115-
this.setRef(ref);
112+
setRef(ref);
116113
} else if (ref?._viewConfig?.validAttributes?.style) {
117114
ref._viewConfig.validAttributes.style = {
118115
...ref._viewConfig.validAttributes.style,
119116
display: false,
120117
};
121-
this.setRef(ref);
118+
setRef(ref);
122119
}
123120
};
124121

@@ -148,9 +145,9 @@ export class InnerScreen extends React.Component<ScreenProps> {
148145
[
149146
{
150147
nativeEvent: {
151-
progress: this.progress,
152-
closing: this.closing,
153-
goingForward: this.goingForward,
148+
progress,
149+
closing,
150+
goingForward,
154151
},
155152
},
156153
],
@@ -168,9 +165,9 @@ export class InnerScreen extends React.Component<ScreenProps> {
168165
) : (
169166
<TransitionProgressContext.Provider
170167
value={{
171-
progress: this.progress,
172-
closing: this.closing,
173-
goingForward: this.goingForward,
168+
progress,
169+
closing,
170+
goingForward,
174171
}}>
175172
{children}
176173
</TransitionProgressContext.Provider>
@@ -195,25 +192,22 @@ export class InnerScreen extends React.Component<ScreenProps> {
195192
return (
196193
<Animated.View
197194
style={[style, { display: activityState !== 0 ? 'flex' : 'none' }]}
198-
ref={this.setRef}
195+
ref={setRef}
199196
{...props}
200197
/>
201198
);
202199
}
203200
}
204-
}
201+
);
205202

206203
// context to be used when the user wants to use enhanced implementation
207204
// e.g. to use `useReanimatedTransitionProgress` (see `reanimated` folder in repo)
208205
export const ScreenContext = React.createContext(InnerScreen);
209206

210-
class Screen extends React.Component<ScreenProps> {
211-
static contextType = ScreenContext;
207+
const Screen: React.FC<ScreenProps> = props => {
208+
const ScreenWrapper = React.useContext(ScreenContext) || InnerScreen;
212209

213-
render() {
214-
const ScreenWrapper = (this.context || InnerScreen) as React.ElementType;
215-
return <ScreenWrapper {...this.props} />;
216-
}
217-
}
210+
return <ScreenWrapper {...props} />;
211+
};
218212

219213
export default Screen;

0 commit comments

Comments
 (0)