繁体   English   中英

socket.io-client 在本机反应中多次发出事件

[英]socket.io-client emmitting event multiple times in react native

I am new to using socket.io with react native.I am able to connect the socket.io instance with my node.js backend but the socket.io client is emmitting events multiple times.The app has grown quite complex so,I am also trying to explain what I did.

Main.js(用户从 App.js 重定向到这里)

我正在使用一个名为 react-native-tab-view 的库,并使用 useContext 来传递套接字实例。我检查了钩子是否正常工作。

export const SocketObj = createContext()
const Main = ({ route }) => {

    let [socket, setSocket] = useState(undefined)

    const routesLength = useNavigationState(state => state.routes.length);

    const connect = async () => {
        if (routesLength == 1) {
            setSocket(io("http://192.168.43.115:8000", {
                transports: ['websocket'],
                query: {
                    token: await AsyncStorage.getItem("token")
                }
            }))
        } else {
            const { socketInstanse } = route.params
            setSocket(socketInstanse)
        }
    }
    connect()

    const layout = useWindowDimensions();

    const [index, setIndex] = useState(0);

    const [routes] = useState([
        { key: 'first', title: 'CHAT' },
        { key: 'second', title: 'PEOPLE' },
    ]);


    const renderScene = SceneMap({
        first: SplashScreen,
        second: PeopleScreen,
    });

    return (
        <SocketObj.Provider value={socket} >
            <TabView
                navigationState={{ index, routes }}
                renderScene={renderScene}
                onIndexChange={(number) => {
                    setIndex(number)
                }}
                initialLayout={{ width: layout.width }}
            />
        </SocketObj.Provider>
    );

}

export default Main;

PeopleScreen.js

用户从 Main.js 定向到此处。 我在这里使用了上下文 api 来获取套接字实例。 如您所见,我正在使用一个事件在连接时将“已连接”记录到控制台,但它会发出多次。我不想多次发出它。帮帮我

import { SocketObj } from "./Main"

const PeopleScreen = ({ route, navigation }) => {

    let socket = useContext(SocketObj)

    socket.on("connect", () => console.log("Connect"))

    const [peopleList, setPeople] = useState([])


    useEffect(
        () => {
            const fetchData = async () => {
                try {
                    const response = await API.get('get/users', {
                        headers: {
                            'Content-Type': 'application/json',
                            "auth-token": await AsyncStorage.getItem("token")
                        }
                    })
                    setPeople(response.data)
                } catch (err) {
                    console.log(err.response)
                }
            }
            fetchData()
        }, []
    )




    return (
        <View style={{
            flex: 1,
            backgroundColor: '#fff',
            width: '100%',
            height: '100%'
        }} >
            <View>
                {
                    peopleList.map(
                        (i, key) => {
                            return (
                                <View style={{
                                    display: 'flex',
                                    flexDirection: 'row',
                                    top: 40,
                                    marginVertical: 5,
                                    marginBottom: 10,
                                    backgroundColor: 'grey',
                                    height: 50

                                }}
                                    key={key} >
                                    <Text style={{
                                        maxWidth: "50%"
                                    }} >{i.firstName + ' ' + i.email}</Text>
                                    <TouchableOpacity
                                        onPress={
                                            async () => {
                                                console.log(socket)
                                                API.post('post/add-friend', {
                                                    friend_email: i.email
                                                }, {
                                                    headers: {
                                                        "auth-token": await AsyncStorage.getItem("token")
                                                    }
                                                }).then(
                                                    data => console.log(data.data)
                                                )
                                            }
                                        }
                                        style={{

                                            backgroundColor: 'rgb(255, 105, 105)',
                                            width: 130,
                                            justifyContent: 'center',
                                            alignItems: 'center',
                                            left: 150
                                        }}
                                        activeOpacity={0.6} >
                                        <Text style={{
                                            color: 'white',
                                        }} >Add Friend</Text>
                                    </TouchableOpacity>
                                </View>
                            )
                        }
                    )
                }
            </View>
        </View >
    )
}

export default PeopleScreen

我忽略了不必要的进口。

尝试将你的connect()放在一个useEffect中,并将一个空数组作为useEffect的第二个参数,然后你的connect function 将仅在 Main.js 的第一次渲染时被调用。


  ...

  const connect = async () => {
    if (routesLength == 1) {
      setSocket(io("http://192.168.43.115:8000", {
        transports: ['websocket'],
        query: {
          token: await AsyncStorage.getItem("token")
        }
      }))
    } else {
      const { socketInstanse } = route.params
      setSocket(socketInstanse)
    }
  }

  useEffect(() => {
    connect();
  }, []);

  ...

  if (!socket) return null;   // or you can return a loading page

  return (
      <SocketObj.Provider value={socket} >
          <TabView
              navigationState={{ index, routes }}
              renderScene={renderScene}
              onIndexChange={(number) => {
                  setIndex(number)
              }}
              initialLayout={{ width: layout.width }}
          />
      </SocketObj.Provider>
  );


这是由于多次初始化套接字而发生的。将实例放在 Main.js 中。 如果套接字实例为空,则初始化套接字。

  { useEffect(() => { if(!isConnected){ connect() } }); 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM