组件使用Apollo订阅渲染了太多次

时间:2019-12-03 20:07:08

标签: javascript reactjs react-native graphql react-apollo

我正在React Native中构建一个聊天应用程序,但是每次渲染时,这些组件都重复渲染20次以上。我尝试使用PureComponentmemo,但还是没有。

我将结构分为3个组成部分:Chat.jsSubChat.js,这是Apollo's doc上使用subscribeToMore显示的结构,并在其中添加了Message.js显示实际消息。

Chat.js

class Chat extends PureComponent {
    render() {
        return (
            <View style={styles.container}>
                <Query
                    query={GET_MESSAGES_QUERY}
                    options={{ fetchPolicy: 'network-only'}}
                >
                    {({ subscribeToMore, ...result }) => (
                        <SubChat
                            {...result}
                            subscribeToNewMessages={() =>
                            subscribeToMore({
                                document: MESSAGE_SUBSCRIPTION,
                                updateQuery: (prev, { subscriptionData }) => {
                                    if (!subscriptionData.data) return prev;
                                    const newMessage = subscriptionData.data.newMessage
                                    if(newMessage.user.id === authId && newMessage.isTyping === true) {
                                        return {
                                            messages: prev.messages
                                        }
                                    }

                                    const indicatorMessages = prev.messages.filter(message => message.isTyping === true && message.user.id !== authId)

                                    if(indicatorMessages) {
                                        prev.messages = prev.messages.filter(message => !indicatorMessages.includes(message))
                                    }

                                    const combinedMessages = prev.messages.concat([newMessage])
                                    return {
                                            messages: combinedMessages
                                        } 
                                    }
                                }) 
                            }
                        /> 
                    )}
                </Query>
            </View>
        )
    }
}  

SubChat.js

const SubChat = ({ 
    subscribeToNewMessages, 
    ...results 
}) => {
    useEffect(() => {
        subscribeToNewMessages()
    }, [])
    const [ chatMessage, setChatMessage ] = useState('')

    // some logic relating to handling message mutation as well as message query
    return (
        <KeyboardAvoidingView 
            style={{ flex: 1 }}
            behavior={Platform.OS === "ios" ? "padding" : null} 
            keyboardVerticalOffset={180}       
        >
            <SafeAreaView style={styles.container}>
                <FlatList 
                    data={messages}
                    renderItem={({ item, index }) => 
                        <Message 
                            item={item} 
                            index={index}              
                        />
                    }
                    keyExtractor={item => item.id.toString()}
                />
                <View style={[styles.input, focus && styles.onFocus]}>
                    <View style={styles.inputContainer} >
                        <TextInput 
                            style={styles.textInput}
                            label="Chat"
                            value={chatMessage}
                            onChangeText={setChatMessage}
                            placeholder = "Write a message"
                            authoCapitalize = "none"
                            multiline
                        />
                    </View>
                </View>
            </SafeAreaView>
        </KeyboardAvoidingView>
    )
}

export default React.memo(SubChat)

最后是Message.js

const Message = ({ 
    item, 
}) => {
    const { text } = !!item && item
    return (
        <View style={styles.container} >
            <Text>{text}</Text>
        </View>
    )
}
export default React.memo(Message)

我不确定是不是导致重新提交的订阅,所以我尝试了以下操作,但仍然没有成功:

    useEffect(() => {
        subscribeToNewMessages()
        return () => subscribeToNewMessages()
    }, [])

更新
我已经将PureComponent的{​​{1}}转换为常规SubChat.js,并包含了Component

shouldComponentUpdate

我还将shouldComponentUpdate(nextProps, nextState) { const { data, members, authId, navigation } = this.props && this.props if (data !== nextProps.data) { return true } if (members !== nextProps.members) { return true } if (authId !== nextProps.authId) { return true } if (navigation !== nextProps.navigation) { return true } if (text !== nextState.text) { return true } if (image !== nextState.image) { return true } if (largImage !== nextState.largImage) { return true } if (chatterId !== nextState.chatterId) { return true } if (myPosts !== nextState.myPosts) { return true } if (theirPosts !== nextState.theirPosts) { return true } if (keycode !== nextState.keycode) { return true } return false } 的功能组件转换为基于类的组件,并包含了Message.js

shouldComponentUpdate

但是,发生相同数量的重新渲染。父组件class Message extends Component { shouldComponentUpdate (nextProps, nextState) { if(this.props.item !== nextProps.item) { return true } return false } render() { return ( <View style={styles.container} > </View> ) } } 仅渲染一次,Chat.js渲染两次,SubChat.js渲染大约20次。

0 个答案:

没有答案