1

I'm gettin undefined in hubConnection, and my program doesn't work, but after refreshing everything works correctly. I've tried to make hubConnection as simple property, but it didn't help me. One more thing that I've already tried is to create useRef hook and check if hubConnection if not undefined, if it not, then block the useEffect, but my messages after this action has stopped work.

Code of the program:

import React, { useCallback, useState, useEffect, useContext } from "react";
import { View, StyleSheet } from "react-native";
import { routes } from "../../../../Environment";
import { Icon } from 'react-native-elements'
import Font from "../../../data/fonts/Font";
import { GiftedChat, Bubble, Send, InputToolbar } from 'react-native-gifted-chat'
import { container } from 'tsyringe';
import ChatService from "../../../../api-service/chat-service/ChatService";
import { AuthContext } from "../../auth/AuthProvider";
import { HubConnection, HubConnectionBuilder } from "@microsoft/signalr";

const Chat = (props: any) => {
    const chatService = container.resolve(ChatService);
    const [messages, setMessages] = useState([]);
    const [message, setMessage] = useState("");
    const [hubConnection, setHubConnection] = useState<HubConnection>();
    const { user } = useContext(AuthContext);
    const getRandomInt = (max: number) => {
        return Math.floor(Math.random() * Math.floor(max));
    }
    useEffect(() => {
        setMessages([
            {
                _id: 1,
                text: 'Hello dude',
                createdAt: new Date(),
                user: {
                    _id: 2,
                    name: 'React Native',
                    avatar: 'https://placeimg.com/140/140/any',
                },
            },
            {
                _id: 2,
                text: 'Hello Tom',
                createdAt: new Date(),
                user: {
                    _id: user?.id.toString()!,
                    name: 'React Native',
                    avatar: 'https://placeimg.com/140/140/any',
                },
            },
            {
                _id: 3,
                text: 'How are you?',
                createdAt: new Date(),
                user: {
                    _id: 2,
                    name: 'React Native',
                    avatar: 'https://placeimg.com/140/140/any',
                },
            },
        ])


        const hubConnectionFunc = new HubConnectionBuilder()
            .withUrl(routes.chatUrl)
            .build();
        hubConnectionFunc?.start().then(() => "Connection started!");
        hubConnectionFunc.on("RecieveMessage", message => {
            console.log(messages[0].text);
            setMessages(previousMessages => GiftedChat.append(previousMessages, {
                _id: getRandomInt(10000),
                text: message,
                createdAt: new Date(),
                user: {
                    _id: user?.id.toString()!,
                    name: 'React Native',
                    avatar: 'https://placeimg.com/140/140/any',
                },
            }))
        })
        setHubConnection(hubConnectionFunc);
        console.log(hubConnection);
    }, [])

    const onSend = useCallback((messages = []) => {
        hubConnection?.invoke("SendMessage", messages[0].text)
            .catch((err: any) => console.log(err));
        setMessage("");
    }, [])


    const renderBubble = (props: any) => {
        return (
            <Bubble
                {...props}
                wrapperStyle={{
                    left: {
                        backgroundColor: "#F1F1F4",
                    },
                    right: {
                        backgroundColor: "#EB7A89"
                    }
                }}
                textStyle={{
                    left: {
                        color: "#000000"
                    },
                    right: {
                        color: "#FFFFFF"
                    }
                }}
            />
        );
    }
    const renderSend = (props: any) => {
        return (
            <Send {...props}>
                <View style={styles.button}>
                    <Icon
                        name='paper-plane'
                        type='font-awesome'
                        color='white'
                    />
                </View>
            </Send>
        )
    }

    const renderInputToolbar = (props: any) => {
        return (
            <InputToolbar {...props} primaryStyle={{
                borderWidth: 2,
                justifyContent: "center",
                alignItems: "center",
                height: 44
            }}
            />
        )
    }

    return (
        <View style={styles.chatWrapper}>
            <GiftedChat
                placeholder="Aa"
                renderTime={() => <View></View>}
                maxInputLength={500}
                messages={messages}
                onInputTextChanged={setMessage}
                text={message}
                onSend={onSend}
                scrollToBottom
                alwaysShowSend
                user={{
                    _id: user?.id.toString()!,
                    name: user?.name!,
                }}
                renderBubble={renderBubble}
                renderSend={renderSend}
                renderInputToolbar={renderInputToolbar}
            />
        </View >
    )
}

NodeJS console after first loading

NodeJS console after refreshing the page

Ramzes
  • 13
  • 4
  • What exactly is undefined, `hubConnection`? Is there an error message stating `hubConnection` is undefined? Where and what is checking/verifying that `hubConnection` is undefined? – Drew Reese Feb 19 '21 at 01:15
  • 1) yes, hubConnection is undefined, after using setHubConnection in useEffect() 2) There is no error, just undefined in hubConnection 3) I'm checking it in the useEffect() in the end, I output it into the console. – Ramzes Feb 19 '21 at 07:04
  • Ah, ok, that's what I originally thought but I wanted confirmation from you. React state updates are asynchronous, so when you console log state it'll be the state from the ***current*** render cycle, not the state you just enqueued for the ***next*** render cycle. If you want to log state updates then use a separate effect just for that state, i.e. something like `useEffect(() => console.log(hubConnection), [hubConnection]);` This effect callback will be triggered when the dependency is updated. – Drew Reese Feb 19 '21 at 07:17
  • Yep, but it gonna kill me, your approach is working, I can see the data, but it works only on the useEffect, if I don't output data in some function(for example onClick event) I get an undefined again. – Ramzes Feb 19 '21 at 07:39
  • I get undefined here `const onSend = useCallback((messages = []) => { console.log(hubConnection); hubConnection?.invoke("SendMessage", messages[0].text) .catch((err: any) => console.log(err)); setMessage(""); }, [])` – Ramzes Feb 19 '21 at 07:46
  • Your other hooks should probably have dependencies `hubConnection` for sure on the `useCallback` since it is undefined on the initial render and the memoized callback should re-enclose any updated `hubConnection` values so it is current. – Drew Reese Feb 19 '21 at 07:48
  • can you help me with that, How can I refresh data inside useCallback () – Ramzes Feb 19 '21 at 08:34
  • `const onSend = useCallback((messages = []) => {....}, [hubConnection, /* include any other dependencies the linter complains about */])`. You may not even need to memoize the `onSend` callback, it's only sent to 1 component and only makes a call to the hub connection to send a message and clears the local message state. these are both asynchronous actions. – Drew Reese Feb 19 '21 at 08:59
  • You are most welcome. – Drew Reese Feb 21 '21 at 19:48

1 Answers1

0

Some of your data not Loading 1st time but when you refresh your screen again it loads your data to fix this issue you can use async-await or && logic

Muhammad Haidar
  • 1,541
  • 16
  • 17