Javascript 如何在React中从Websocket获取数据?
我正在尝试从bitstamp API获取实时数据,并将其存储在我的订单状态。页面陷入循环并耗尽资源,并且在订单状态更改时不会重新呈现页面。如果我将数据记录到控制台,我可以看到它 这就是我到目前为止已经实现的Javascript 如何在React中从Websocket获取数据?,javascript,reactjs,websocket,Javascript,Reactjs,Websocket,我正在尝试从bitstamp API获取实时数据,并将其存储在我的订单状态。页面陷入循环并耗尽资源,并且在订单状态更改时不会重新呈现页面。如果我将数据记录到控制台,我可以看到它 这就是我到目前为止已经实现的 const [loading, setLoading] = useState(true); const [orders, setOrders] = useState([]); const [subscription, setSubscription] = useState({
const [loading, setLoading] = useState(true);
const [orders, setOrders] = useState([]);
const [subscription, setSubscription] = useState({
event: 'bts:subscribe',
data: {
channel: 'order_book_btcusd'
}
});
const ws = new WebSocket('wss://ws.bitstamp.net');
const initWebsocket = () => {
ws.onopen = () => {
ws.send(JSON.stringify(subscription));
};
ws.onmessage = (event) => {
const response = JSON.parse(event.data);
switch (response.event) {
case 'data':
setOrders(response.data);
setLoading(false);
break;
case 'bts:request_reconnect':
initWebsocket();
break;
default:
break;
}
};
ws.onclose = () => {
initWebsocket();
};
};
useEffect(() => {
initWebsocket();
}, [orders, subscription]);
console.log(orders);
const showResult = () => {
orders.bids.map((el, index) => (
<tr key={index}>
<td> {el[0]} </td>
<td> {el[1]} </td>
</tr>
));
};
const[loading,setLoading]=useState(true);
const[orders,setOrders]=useState([]);
常量[subscription,setSubscription]=useState({
事件:“bts:订阅”,
数据:{
频道:“订购书”
}
});
const ws=新的WebSocket('wss://ws.bitstamp.net');
常量initWebsocket=()=>{
ws.onopen=()=>{
发送(JSON.stringify(订阅));
};
ws.onmessage=(事件)=>{
const response=JSON.parse(event.data);
开关(response.event){
案例“数据”:
设置订单(响应数据);
设置加载(假);
打破
案例“基站:请求重新连接”:
initWebsocket();
打破
违约:
打破
}
};
ws.onclose=()=>{
initWebsocket();
};
};
useffect(()=>{
initWebsocket();
},[订单、认购];
控制台日志(订单);
常量showResult=()=>{
orders.bids.map((el,索引)=>(
{el[0]}
{el[1]}
));
};
发生这种情况是因为useffect
在每个渲染周期后执行回调,即在第一次渲染和每次更新后都运行回调。因此,对于收到的每个第一条消息,它都会打开一个新的WebSocket连接,并将数据存储在导致循环的状态中
编辑:-
useEffect(() => {
initWebsocket();
}, [orders, subscription]);
useffect
的可选第二个参数用于检测是否有任何更改(基本上它比较prev state/props和给定state/props),并在值发生更改时调用effect
因此,在每次命令状态更新时,都会调用此效果,从而导致循环
解决方案:-
但是,在您的情况下,您只希望在安装组件后建立一次WebSocket连接,并保持侦听传入数据,而不考虑任何状态或属性更改。
您可以传递空[],以便在装载和卸载时只调用它一次
useffect(()=>{
initWebsocket();
//将在下次执行之前调用的清理方法。在您的情况下,请卸载。
return()=>{
ws.close
}
}, []);
从文件:-
这个需求非常常见,它被内置到useEffect钩子API中。如果在重新渲染之间某些值没有更改,则可以告诉React to skip应用效果。为此,将数组作为可选的第二个参数传递给useEffect
如果希望运行一个效果并只清理一次(装载和卸载时),可以将空数组([])作为第二个参数传递。这告诉React,您的效果不依赖于道具或状态的任何值,因此它永远不需要重新运行。这并不是作为特例处理的——它直接遵循依赖项数组的工作方式
如果传递空数组([]),效果中的道具和状态将始终具有其初始值。虽然传递[]作为第二个参数更接近熟悉的componentDidMount和componentWillUnmount心智模型,但通常有更好的解决方案来避免过于频繁地重新运行效果
发生这种情况的原因是
useffect
在每个渲染周期后执行其回调,即它在第一次渲染后和每次更新后都运行。因此,对于收到的每个第一条消息,它都会打开一个新的WebSocket连接,并将数据存储在导致循环的状态中
编辑:-
useEffect(() => {
initWebsocket();
}, [orders, subscription]);
useffect
的可选第二个参数用于检测是否有任何更改(基本上它比较prev state/props和给定state/props),并在值发生更改时调用effect
因此,在每次命令状态更新时,都会调用此效果,从而导致循环
解决方案:-
但是,在您的情况下,您只希望在安装组件后建立一次WebSocket连接,并保持侦听传入数据,而不考虑任何状态或属性更改。
您可以传递空[],以便在装载和卸载时只调用它一次
useffect(()=>{
initWebsocket();
//将在下次执行之前调用的清理方法。在您的情况下,请卸载。
return()=>{
ws.close
}
}, []);
从文件:-
这个需求非常常见,它被内置到useEffect钩子API中。如果在重新渲染之间某些值没有更改,则可以告诉React to skip应用效果。为此,将数组作为可选的第二个参数传递给useEffect
如果希望运行一个效果并只清理一次(装载和卸载时),可以将空数组([])作为第二个参数传递。这告诉React,您的效果不依赖于道具或状态的任何值,因此它永远不需要重新运行。这并不是作为特例处理的——它直接遵循依赖项数组的工作方式
如果传递空数组([]),效果中的道具和状态将始终具有其初始值。虽然传递[]作为第二个参数更接近熟悉的componentDidMount和componentWillUnmount心智模型,但通常有更好的解决方案来避免过于频繁地重新运行效果
在
useffect
中,在初始化WebSocket连接之前检查其是否已关闭
如果您对react hooks的工作感到困惑,可以使用类组件并在componentDidMount
和componentdiddupdate
中初始化WebSocket连接(检查连接是否关闭并初始化i