日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
如何在React中正確的使用socket.io客戶端?

在本文中,將會給大家分享下我在 React 中使用 Socket.io 客戶端的一些經(jīng)驗(yàn),希望對此有疑惑的朋友給予一些幫助,也許你會有一些更好的實(shí)現(xiàn)方式,歡迎交流!

網(wǎng)站建設(shè)哪家好,找成都創(chuàng)新互聯(lián)!專注于網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、重慶小程序開發(fā)公司、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了洪洞免費(fèi)建站歡迎大家使用!

創(chuàng)建 Socket Context

本文的實(shí)現(xiàn)方式是使用狀態(tài)管理工具保存 socket 實(shí)例,供子組件使用,如果使用了 React Hooks,可以用其提供的 useContext API,實(shí)現(xiàn)起來也很簡單。

// contexts/socket.tsx
import { createContext, ReactNode, useContext } from 'react';
import io, { Socket } from 'socket.io-client';

const SOCKET_URL = 'ws://localhost:8080';
export const socket = io(SOCKET_URL, {
transports: ['websocket'],
});

const SocketContext = createContext(socket);
SocketContext.displayName = 'SocketContext';

export const SocketProvider = ({ children }: { children: ReactNode }) => (
{children}
);

export const useSocket = () => {
const context = useContext(SocketContext);
return context;
};

// contexts/index.tsx
import { ReactNode } from 'react';
import { SocketProvider } from './Socket';

const AppContextProviders = ({ children }: { children: ReactNode }) => (
{children}
);

export default AppContextProviders;

其中  const socket = io(SOCKET_URL)?,有些朋友可能就有疑問了,為什么不執(zhí)行下 socket.connect() 呢?

socket.io 客戶端默認(rèn)是自動鏈接的,如果聲明了 autoConnect 屬性為 false,則需要手動執(zhí)行下鏈接。

以上,在頁面第一次加載時(shí)會初始化 socket,解決了第一個(gè)問題:“React 單頁面應(yīng)用中如何防止出現(xiàn)多個(gè) socket 實(shí)例”。

根組件提供 socket

在項(xiàng)目的 App.js 文件中引入我們自定義的 Providers,將 AppProviders 組件做為根組件放在最頂層,這樣被包裹的組件都可以使用 AppProviders 組件提供的屬性。也解決了第二個(gè)問題:“在任意的的組件內(nèi)如何方便的取到 socket 實(shí)例”。

import AppProviders from './contexts';
import './App.css';

const App = () => (

...

);

export default App;

任意子組件中使用 socket

組件 A,監(jiān)聽服務(wù)器發(fā)來的消息。

useEffect() 是 React 內(nèi)置的一個(gè) Hook,如果第二個(gè)參數(shù)依賴項(xiàng)數(shù)組為空,那么傳入的第一個(gè)函數(shù)在該組件內(nèi)只會執(zhí)行一次,依賴項(xiàng)數(shù)組只要有一個(gè)狀態(tài)被更新,useEffect() 傳入的第一個(gè)函數(shù)也將會被執(zhí)行。

還需要注意的是 useEffect() 傳入的第一個(gè)函數(shù),它又返回的函數(shù)在函數(shù)組件卸載時(shí)被調(diào)用,通常我們會用 useEffect() 模擬類組件的 componentDidMount、componentWillUnmount 行為。

在組件卸載時(shí),使用 socket.off() 移除事件監(jiān)聽器,實(shí)際上這可以預(yù)防內(nèi)存泄漏,同時(shí)也解決了最開始提的第三個(gè)問題:“對于某個(gè)事件不要隨著頁面切換出現(xiàn)多個(gè)監(jiān)聽器”。

import { useEffect } from 'react';
import { useSocket } from '../../contexts/Socket';

const ComponentA = () => {
const socket = useSocket();

useEffect(() => {
// componentDidMount
socket.on('message', handleMessage); // 監(jiān)聽消息
return () => {
// componentWillUnmount
socket.off('message', handleMessage);
};
}, [socket]);

return ();
};

export default ComponentA;

組件 B,發(fā)送消息到服務(wù)器。

在我們的組件 B 中,也可以使用自定義的 useSocket Hook 獲取最開始初始化的 socket 實(shí)例,但這并不會產(chǎn)生一個(gè)新的 socket 實(shí)例。

import { useEffect } from 'react';
import { useSocket } from '../../contexts/Socket';

const ComponentB = () => {
const socket = useSocket();
const handleSendMessage = () => {
socket.emit('compress', data); // 發(fā)送消息
}

return

// ...

;
};

export default ComponentB;


網(wǎng)頁名稱:如何在React中正確的使用socket.io客戶端?
路徑分享:http://m.5511xx.com/article/cdpshhs.html