Skip to content

Commit 3cc7fe9

Browse files
authored
Merge pull request #612 from hy916/dev
fix(Modal):优化Modal组件代码和文档示例
2 parents 7ce2e18 + bfa34d1 commit 3cc7fe9

File tree

2 files changed

+52
-44
lines changed

2 files changed

+52
-44
lines changed

example/examples/src/routes/Modal/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ export default class ModalView extends Component<ModalViewProps> {
4343
// Alert.alert('Modal has been closed.');
4444
}}>
4545
<SafeAreaView>
46-
<View>
46+
<View style={{height: 400}}>
4747
<Text>Hello World!</Text>
4848
<Button onPress={() => this.setModalVisible(!this.state.modalVisible)}>隐藏模态框</Button>
4949
<Text>Hello World!</Text>

packages/core/src/Modal/index.tsx

Lines changed: 51 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import React, { useState, useMemo, useRef } from 'react';
1+
import React, { useState, useMemo, useRef, useEffect } from 'react';
22
import { Animated, StyleSheet, LayoutChangeEvent, Dimensions, ViewStyle } from 'react-native';
33
import MaskLayer, { MaskLayerProps } from '../MaskLayer';
44
import { Theme } from '../theme';
55
import { useTheme } from '@shopify/restyle';
66

7-
let MainWidth = Dimensions.get('window').width;
8-
let MainHeight = Dimensions.get('window').height;
7+
const MainWidth = Dimensions.get('window').width;
8+
const MainHeight = Dimensions.get('window').height;
99

1010
export interface ModalProps extends MaskLayerProps {
1111
placement?: 'top' | 'right' | 'bottom' | 'left';
@@ -16,27 +16,14 @@ export interface ModalProps extends MaskLayerProps {
1616
const Modal = (props: ModalProps = {}) => {
1717
const { onClosed, visible, children, placement = 'bottom', containerStyle, ...otherProps } = props;
1818
const theme = useTheme<Theme>();
19-
const AnimatedOpacity: Animated.Value = useRef(new Animated.Value(0)).current;
20-
// const [display] = useState<'none' | 'flex'>('none');
21-
let [layoutHeight, setLayoutHeight] = useState(0);
22-
let [layoutWidth, setLayoutWidth] = useState(0);
19+
const AnimatedOpacity = useRef(new Animated.Value(0)).current;
20+
const [layoutHeight, setLayoutHeight] = useState(0);
21+
const [layoutWidth, setLayoutWidth] = useState(0);
2322
const [translateValue] = useState(new Animated.Value(0));
2423
const isVertical = /^(top|bottom)$/.test(placement);
2524
const isHorizontal = /^(left|right)$/.test(placement);
26-
function onDismiss() {
27-
onClosed && onClosed();
28-
}
29-
function measureContainer(event: LayoutChangeEvent) {
30-
const { height, width } = event.nativeEvent.layout;
31-
if (!layoutHeight && isVertical) {
32-
setLayoutHeight(height);
33-
}
34-
if (!layoutWidth && isHorizontal) {
35-
setLayoutWidth(width);
36-
}
37-
}
3825

39-
useMemo(() => {
26+
useEffect(() => {
4027
function getTransformSize() {
4128
if (placement === 'top') {
4229
return -layoutHeight;
@@ -56,20 +43,18 @@ const Modal = (props: ModalProps = {}) => {
5643
if (!result) return;
5744
if (visible) {
5845
translateValue.setValue(result);
59-
// AnimatedOpacity
60-
Animated.timing(AnimatedOpacity, {
61-
toValue: 1,
62-
duration: 0,
63-
useNativeDriver: false,
64-
}).start(({ finished }) => {
65-
Animated.parallel([
66-
Animated.spring(translateValue, {
67-
toValue: 0,
68-
overshootClamping: true,
69-
useNativeDriver: true,
70-
}),
71-
]).start();
72-
});
46+
Animated.parallel([
47+
Animated.timing(AnimatedOpacity, {
48+
toValue: 1,
49+
duration: 0,
50+
useNativeDriver: false,
51+
}),
52+
Animated.spring(translateValue, {
53+
toValue: 0,
54+
overshootClamping: true,
55+
useNativeDriver: true,
56+
}),
57+
]).start();
7358
}
7459
if (!visible) {
7560
Animated.parallel([
@@ -78,10 +63,15 @@ const Modal = (props: ModalProps = {}) => {
7863
overshootClamping: true,
7964
useNativeDriver: true,
8065
}),
66+
Animated.timing(AnimatedOpacity, {
67+
toValue: 0,
68+
duration: 0,
69+
useNativeDriver: false,
70+
}),
8171
]).start();
8272
}
83-
// eslint-disable-next-line react-hooks/exhaustive-deps
84-
}, [visible, layoutHeight, layoutWidth]);
73+
}, [visible, layoutHeight, layoutWidth, placement, translateValue, AnimatedOpacity]);
74+
8575
const translateStyle = {} as {
8676
translateY: Animated.Value;
8777
translateX: Animated.Value;
@@ -92,19 +82,25 @@ const Modal = (props: ModalProps = {}) => {
9282
if (isHorizontal) {
9383
translateStyle.translateX = translateValue;
9484
}
95-
const child = React.useMemo(
85+
86+
const child = useMemo(
9687
() => (
9788
<Animated.View
9889
style={[styles.content, placement && styles[placement], { opacity: AnimatedOpacity }, containerStyle]}
9990
>
10091
<Animated.View
101-
onLayout={measureContainer}
92+
onLayout={(event: LayoutChangeEvent) => {
93+
const { height, width } = event.nativeEvent.layout;
94+
if (!layoutHeight && isVertical) {
95+
setLayoutHeight(height);
96+
}
97+
if (!layoutWidth && isHorizontal) {
98+
setLayoutWidth(width);
99+
}
100+
}}
102101
style={[
103102
styles.content,
104103
placement && styles[placement],
105-
// !layoutHeight && isVertical ? { display: display } : {},
106-
// !layoutWidth && isHorizontal ? { display: display } : {},
107-
// // getTransformStyle(),
108104
{
109105
transform: [translateStyle],
110106
backgroundColor: theme.colors.mask || '#fff',
@@ -117,10 +113,22 @@ const Modal = (props: ModalProps = {}) => {
117113
</Animated.View>
118114
</Animated.View>
119115
),
120-
[children],
116+
[
117+
children,
118+
AnimatedOpacity,
119+
containerStyle,
120+
isHorizontal,
121+
isVertical,
122+
layoutHeight,
123+
layoutWidth,
124+
placement,
125+
theme.colors.mask,
126+
translateStyle,
127+
],
121128
);
129+
122130
return (
123-
<MaskLayer {...otherProps} visible={visible} onDismiss={onDismiss}>
131+
<MaskLayer {...otherProps} visible={visible} onDismiss={onClosed}>
124132
{child}
125133
</MaskLayer>
126134
);

0 commit comments

Comments
 (0)