抽屉打开/关闭时,抽屉的屏幕组件正在重新渲染

时间:2020-09-30 11:21:05

标签: reactjs react-native react-navigation react-navigation-v5 react-navigation-drawer

我有带多个屏幕的主Stack导航器,其中一个屏幕是具有动态创建屏幕的嵌套Drawer导航器。

<Provider store={store}>
            <NavigationContainer onStateChange={onStateChange}>
                <Stack.Navigator initialRouteName="Launch">
                    <Stack.Screen name="Launch" component={Launch} />
                    <Stack.Screen name="Login" component={Login} />
                    <Stack.Screen name="Home" component={Home} />
                    <Stack.Screen name="ChatBox" component={ChatBox} /> /* <- Here is the drawer navigator screen */
                </Stack.Navigator>
            </NavigationContainer>
</Provider>

正如您在the example gif中所见,在执行抽屉操作时,ChatComponent总是重新渲染。即使在抽屉列表中当前屏幕没有更改,它也会执行该操作。

<Drawer.Navigator>
                        {userChannels.map((channel, index) => {
                            const chatName = userChannels[index].friendlyName;
                            const screen = React.memo(() => (
                                <View style={{ flex: 1 }}>
                                    <Header text={chatName} />
                                    <ChatComponent
                                        channel={channel}
                                        loadEarlier={loadEarlier}
                                        isLoadingEarlier={isLoadingEarlier}
                                        onLoadEarlier={onLoadEarlier}
                                        savedMessages={savedMessages}
                                        onSend={onSend}
                                        isTyping={isTyping}
                                        user={{
                                            _id: me.member.sid || 0,
                                        }}
                                        onInputTextChanged={async () => {
                                            currentChannel &&
                                                (await currentChannel.typing());
                                        }}
                                        enterChannel={() =>
                                            enterChannel(channel.uniqueName)
                                        }
                                    />
                                </View>
                            ));
                            return (
                                <Drawer.Screen
                                    key={index}
                                    name={chatName || String(index)}
                                    component={screen}
                                />
                            );
                        })}
</Drawer.Navigator>

标头组件是:

export default (props) => {
    const { text } = props;
    const navigation = useNavigation();

    const logout = async () => {
        try {
            await AsyncStorage.removeItem('accessToken');
            await AsyncStorage.removeItem('refreshToken');
        } catch (e) {
            // 
        }

        navigation.navigate('Login');
    };

    return (
        <View style={styles.header}>
            <TouchableOpacity
                onPress={() => navigation.dispatch(DrawerActions.openDrawer())}>
                <Icon name="menu" color="#FFF" size={18} />
            </TouchableOpacity>
            {text && <Text style={styles.headerText}>{text}</Text>}
            <Text style={styles.headerText} onPress={logout}>
                Logout
            </Text>
        </View>
    );
};

聊天组件是:

const ChatComponent = React.memo((props) => {
    const {
        channel,
        loadEarlier,
        isLoadingEarlier,
        onLoadEarlier,
        savedMessages,
        onSend,
        isTyping,
        user,
        onInputTextChanged,
        enterChannel,
    } = props;
        
    useEffect(() => {
        console.log('render ChatComponent');                        
        enterChannel();
        
    }, []);

    return (
        <GiftedChat
            inverted={false}
            loadEarlier={loadEarlier}
            isLoadingEarlier={isLoadingEarlier}
            onLoadEarlier={onLoadEarlier}
            messages={savedMessages}
            onSend={onSend}
            user={user}
            onInputTextChanged={onInputTextChanged}
            isTyping={isTyping}
            renderBubble={renderBubble}
            renderTime={renderTime}
            renderInputToolbar={renderInputToolbar}            
        />
    );
});

这里是the onStateChange of NavigationContainer

如何避免不必要地渲染ChatComponent?

0 个答案:

没有答案