Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/424.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在React中从Websocket获取数据?_Javascript_Reactjs_Websocket - Fatal编程技术网

Javascript 如何在React中从Websocket获取数据?

Javascript 如何在React中从Websocket获取数据?,javascript,reactjs,websocket,Javascript,Reactjs,Websocket,我正在尝试从bitstamp API获取实时数据,并将其存储在我的订单状态。页面陷入循环并耗尽资源,并且在订单状态更改时不会重新呈现页面。如果我将数据记录到控制台,我可以看到它 这就是我到目前为止已经实现的 const [loading, setLoading] = useState(true); const [orders, setOrders] = useState([]); const [subscription, setSubscription] = useState({

我正在尝试从bitstamp API获取实时数据,并将其存储在我的订单状态。页面陷入循环并耗尽资源,并且在订单状态更改时不会重新呈现页面。如果我将数据记录到控制台,我可以看到它

这就是我到目前为止已经实现的

  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