Javascript 在react native中多次发生socket.io-client emmitting事件
我不太熟悉使用socket.io和react native。我可以将socket.io实例与node.js后端连接起来,但socket.io客户端多次发送事件。该应用程序变得相当复杂,因此,我也尝试解释我所做的 Main.js(用户从App.js重定向到此) 我正在使用一个名为react native tab view的库,并使用useContext传递套接字实例。我已检查挂钩是否正常工作Javascript 在react native中多次发生socket.io-client emmitting事件,javascript,reactjs,react-native,socket.io,Javascript,Reactjs,React Native,Socket.io,我不太熟悉使用socket.io和react native。我可以将socket.io实例与node.js后端连接起来,但socket.io客户端多次发送事件。该应用程序变得相当复杂,因此,我也尝试解释我所做的 Main.js(用户从App.js重定向到此) 我正在使用一个名为react native tab view的库,并使用useContext传递套接字实例。我已检查挂钩是否正常工作 export const SocketObj = createContext() const Main =
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;
export const SocketObj=createContext()
常量Main=({route})=>{
let[socket,setSocket]=useState(未定义)
const routesLength=useNavigationState(state=>state.routes.length);
const connect=async()=>{
if(routesLength==1){
设置锁(io)http://192.168.43.115:8000", {
传输:['websocket'],
查询:{
令牌:等待AsyncStorage.getItem(“令牌”)
}
}))
}否则{
const{socketInstanse}=route.params
固定套筒(套筒)
}
}
连接()
常量布局=使用WindowDimensions();
const[index,setIndex]=useState(0);
常量[路由]=使用状态([
{key:'first',title:'CHAT'},
{键:'second',标题:'PEOPLE'},
]);
const renderScene=SceneMap({
第一:SplashScreen,
第二:人屏,
});
返回(
{
设置索引(编号)
}}
initialLayout={{width:layout.width}
/>
);
}
导出默认主;
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
从“/Main”导入{SocketObj}
const PeopleScreen=({route,navigation})=>{
let socket=useContext(SocketObj)
socket.on(“连接”),()=>console.log(“连接”))
常量[peopleList,setPeople]=useState([])
使用效果(
() => {
const fetchData=async()=>{
试一试{
const response=wait API.get('get/users'{
标题:{
“内容类型”:“应用程序/json”,
“身份验证令牌”:等待AsyncStorage.getItem(“令牌”)
}
})
setPeople(response.data)
}捕捉(错误){
console.log(错误响应)
}
}
fetchData()
}, []
)
返回(
{
peopleList.map(
(i,键)=>{
返回(
{i.firstName+''+i.email}
{
控制台日志(套接字)
API.post('post/add friend'{
朋友的电子邮件:i.email
}, {
标题:{
“身份验证令牌”:等待AsyncStorage.getItem(“令牌”)
}
}).那么(
data=>console.log(data.data)
)
}
}
风格={{
背景颜色:“rgb(255,105,105)”,
宽度:130,
为内容辩护:“中心”,
对齐项目:“居中”,
左:150
}}
activeOpacity={0.6}>
加朋友
)
}
)
}
)
}
导出默认人屏幕
我忽略了不必要的导入。尝试将您的
connect()
放在useffect
中,并将空数组作为useffect
的第二个参数,然后您的connect
函数将仅在Main.js的第一次呈现时调用
...
const connect=async()=>{
if(routesLength==1){
设置锁(io)http://192.168.43.115:8000", {
传输:['websocket'],
查询:{
令牌:等待AsyncStorage.getItem(“令牌”)
}
}))
}否则{
const{socketInstanse}=route.params
固定套筒(套筒)
}
}
useffect(()=>{
connect();
}, []);
...
如果(!socket)返回null;//或者您可以返回一个加载页面
返回(
{
设置索引(编号)
}}
initialLayout={{width:layout.width}
/>
);
这是由于多次初始化套接字造成的。请将实例放在Main.js中。
如果套接字实例为空,则初始化套接字
{ useEffect(() => { if(!isConnected){ connect() } });
尝试关闭手机上的应用程序并重新运行,看看发生了什么!?我重新运行了多次,但没有任何更改。我这么做了,但是它说套接字没有定义。尝试使用我放在编辑代码上的
if
语句。