gpt4 book ai didi

javascript - 如何使用 Context API 将单个 Socket IO 实例传递给页面?

转载 作者:行者123 更新时间:2023-11-30 06:14:17 25 4
gpt4 key购买 nike

所以我试图在我的整个应用程序中使用一个单一的 Socket IO 实例并从多个组件访问它。

我已经搜索了很多,也尝试了很多...但都没有成功。

我现在正在使用 React Context API。

我在 SocketProvider.js 中初始化我的 SocketContext:

import React from 'react'

const SocketContext = React.createContext()

export default SocketContext

打开套接字并在 App.js 中提供它:

import React from 'react';
import Main from './components/Main/Main';
import io from 'socket.io-client';
import SocketContext from './services/SocketProvider'


function App() {
const socket = io("http://localhost:8000")
return (
<div className="App">
<SocketContext.Provider value={socket}>
<MuiPickersUtilsProvider>
<MuiThemeProvider >
<Main />
</MuiThemeProvider>
</MuiPickersUtilsProvider>
</SocketContext.Provider>
</div>
);
}

export default App;

Main.js 中的路由:


function Main() {

return (
<main>
<Switch>
<Route exact path="/" component={Menu} />

<Route path="/panorama" component={Panorama} />
<Route path="/movie" component={Movie} />

<Route
path="/timelapse"
render={({ match: { url } }) => (
<>
<Route path={`${url}/`} component={Timelapse} exact />
<Route path={`${url}/running`} render={(props) => <Running {...props} type={'timelapse'} />} />

</>
)}
/>

</Switch>
</main>
);
}


export default Main;

并在这两个组件中使用它,Timelapse.js:

import React from 'react';
import SocketContext from '../../services/SocketProvider';
import TimelapsePoints from '../../components/TimelapsePoints/TimelapsePoints';
import TimelapseCamControls from '../../components/TimelapseCamControls/TimelapseCamControls'


class Timelapse extends React.Component {
constructor(props) {
super(props);

let socket = props.socket;

this.state = {
hasCamera: false,
cameraActive: false,
brightnessControl: false,
camControlsOk: false,
pointsOk: false,
interval: 10,
recordingTime: 6000,
movieTime: 12
};

socket.on('hasCamera', data => {
this.setState({
cameraActive: data.hasCamera
})
this.setState({
hasCamera: data.hasCamera
})
})
}


render() {
return (<div >
{
this.state.cameraActive &&
<TimelapseCamControls brightnessControl={
this.state.brightnessControl
}
toggleBrightnesscontrol={
this.toggleBrightnesscontrol
}
camControlsOk={
this.camControlsOk
}
socket={
this.props.socket
}
/>
} {
(!this.state.brightnessControl || (this.state.brightnessControl && this.state.camControlsOk)) &&


<TimelapsePoints socket={this.props.socket} handlePointsChange={this.pointsOk}/>

{this.state.pointsOk && this.camControlsOk &&
<Button variant="outlined" onClick={this.timelapse} href="/timelapse/running">
Start
</Button>
}
</div>
);
}
}

const TimelapseWithSocket = (props) => (
<SocketContext.Consumer>
{socket => <Timelapse {...props} socket={socket} />}
</SocketContext.Consumer>
)
export default TimelapseWithSocket;

Running.js:

import React from 'react';
import SocketContext from '../../services/SocketProvider';

class Running extends React.Component {
constructor(props) {
super(props);

this.state = {
progress: 0,
maxProgress: 100,
waypoints: []
};

}


componentDidMount() {
this.props.socket.on('progress', data => {
this.setState({
progress: data.value,
maxProgress: data.max
})
})

this.props.socket.on('timelapseInfo', data => {
console.log('recived date');
this.setState({
waypoints: data.waypoints,
maxProgress: data.max
})
})

console.log("component mounte");
}



render() {
var type = this.props.type;
var title = type.charAt(0).toUpperCase() + type.slice(1)

return (<div >

</div>
);
}
}

const RunningWithSocket = (props) => (
<SocketContext.Consumer>
{socket => <Running {...props} socket={socket} />}
</SocketContext.Consumer>
)

export default RunningWithSocket;

但是当我到达路线 /timelapse/running 时,我得到了一个新的 Socket 实例,但我不知道为什么以及如何修复它。

感谢您的帮助:)

最佳答案

要获得相同的结果,您不需要 Context API,只需从模块中导出 websocket 连接即可:

// ws.js
import io from 'socket.io-client'

const ws = io.connect(<host>)

export { ws }

然后你可以在你的组件中使用 useEffect(fn, []) 添加事件,两个方括号作为第二个参数用于使效果只运行一次:

// wsComponent.js
import React, { useState, useEffect } from 'react'
import { Text } from 'react-native'
import { ws } from 'ws.js'

const WsComponent = () => {
const [wsState, updateWsState] = useState(false)
useEffect(() => {
ws.on('connect', () => {
updateWsState(true)
})
ws.on('disconnect', () => {
updateWsState(false)
})
}, [])
return (
<Text>{wsState ? 'ONLINE' : 'OFFLINE'}</Text>
)
}

export { WsComponent }

对不起,如果我在代码中犯了错误,我没有测试它。

关于javascript - 如何使用 Context API 将单个 Socket IO 实例传递给页面?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57179948/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com