如何在 React Native 中处理客户端 Websocket 数据流,因为状态经常变化,我的屏幕被冻结了

How To Handle Client Side Websocket Data Stream in React Native, As The State is Changing Frequently My Screen Are Getting Frozen

提问人:Badineni Saivardhan 提问时间:1/5/2023 更新时间:1/6/2023 访问量:530

问:

我正在使用 React Native 从数据提供商使用 Websocket 提供的数据中构建一个客户端模拟交易应用程序,假设如果我订阅“A”和“B”和...,我在 websocket 流中获取它们的数据。.我尝试使用 usestate 将数据置于状态中,并将其附加到以前的状态并将其传递给组件,它正在重新演绎整个组件,因为状态变化太频繁,因为数据变化非常频繁......请帮我如何处理频繁更改的数据

注意:这是一个 websocket 流,过于频繁的状态更改导致重新渲染会导致性能问题,如果有任何可能的有效方法来处理 react native 中过于频繁的数据更改,请建议......实时获取的数据只需要显示,而不是保存和显示在UI上,而不会影响性能

这是我的主屏幕代码:

import { View, Text, SafeAreaView, Image, Dimensions, TouchableOpacity } from 'react-native'
import React, { useEffect, useState } from 'react'
import HomeScreenChart from './HomeScreenChart'
import { ScrollView } from 'react-native-gesture-handler'
import Strikes from './Strikes';

const url = "WebsocketURL";
var ws = new WebSocket(url);

const width = Dimensions.get('window').width
const height = Dimensions.get('window').height
const SPACING = 12

export default function HomeScreen() {
var recieveddata = []
var requestArray = ["nse_cm_nifty_50","nse_cm_nifty_bank","nse_fno_banknifty_05012023_43000_ce","nse_fno_banknifty_05012023_43000_pe","nse_fno_banknifty_05012023_43100_ce","nse_fno_banknifty_05012023_43100_pe","nse_fno_banknifty_05012023_43200_ce","nse_fno_banknifty_05012023_43200_pe","nse_fno_banknifty_05012023_43300_ce","nse_fno_banknifty_05012023_43300_pe","nse_fno_banknifty_05012023_43400_ce","nse_fno_banknifty_05012023_43400_pe","nse_fno_banknifty_05012023_43500_ce","nse_fno_banknifty_05012023_43500_pe"]
const [marketData, setmarketData] = useState({})
const CallWebSocket = async () =>{
ws.onopen = () => {
var requestString = ''
for (var i=0;i<requestArray.length;i++){
if(i==requestArray.length-1){
requestString = requestString+requestArray[i]
}else{
requestString = requestString+requestArray[i]+','
}
}
ws.send('type=msubscribe&'+requestString+'&columns=20'); // send a message
};
ws.onmessage =  async e => {
var text =  new Response(e.data).text();
text.then( (res)=>{
recieveddata = []
var responsedata = res.split('\n')
for  (var i=0;i<responsedata.length-2;i++){
var tempdata = responsedata[i].split('|')
recieveddata.push(`{index:${i}, name:${tempdata[0]}, value:${tempdata[1]}}`)               
}
//console.log(recieveddata)
})
};
ws.onerror = e => {
console.log(e.message);
};
ws.onclose = e => {
console.log(e.code, e.reason);
};

}
useEffect(() => {
CallWebSocket()
}, [])



return (
<SafeAreaView style={{flex:1 ,backgroundColor:'#ebecee',shadowColor:'black',borderBottomStartRadius:10,borderBottomEndRadius:10}}>
<View>
<View style={{padding:20}}>
<Text style={{fontSize:30,fontWeight:'bold'}}>Marketwatch</Text>
</View>
<View style={{flexDirection:'row',marginTop:5,justifyContent:'space-around'}}>
<View style={{flexDirection:'column'}} >
<Text style={{fontSize:25, color:'#4c80cf', fontWeight:'500',textAlign:'center'}}> NIFTY 50 </Text>
<TouchableOpacity><Text style={{fontSize:30, fontWeight:'800',alignSelf:'center'}}>{marketData.nse_cm_nifty_50}</Text></TouchableOpacity>
</View>
<View style={{flexDirection:'column'}} >
<Text style={{fontSize:25, fontWeight:'500'}}> BANK NITFTY</Text>
<TouchableOpacity><Text style={{fontSize:30, fontWeight:'800',alignSelf:'center'}}>{marketData.nse_cm_nifty_bank}</Text></TouchableOpacity>
</View>
</View>
<View style={{width:width-20,borderRadius:5,backgroundColor:'#810a0a',height:60,justifyContent:'space-around',alignItems:'center',alignSelf:'center',marginTop:10,marginBottom:5,flexDirection:'row'}}>
<Text style={{color:'white',fontSize:25,fontWeight:'400'}}>Expiry </Text>
<Text style={{color:'white',fontSize:25,fontWeight:'400'}}>5-DEC-2023</Text>
</View>
</View>
<ScrollView style={{flex:1 ,backgroundColor:'white',width:width,marginTop:5,height:height}} showsVerticalScrollIndicator={false}>
<View style={{flex:1, padding:20,flexDirection:'row',alignItems:'center',justifyContent:'space-between',marginTop:5,marginBottom:0}}>
<Text style={{color:'green',fontSize:15,fontWeight:'800'}}>CALLS</Text>
<Text style={{color:'black',fontSize:20,fontWeight:'800',textDecorationLine:'underline'}}>STRIKE</Text>
<Text style={{color:'red',fontSize:15,fontWeight:'800'}}>PUTS </Text>
</View>
<View style={{ borderBottomColor: '#ebecee', borderBottomWidth:2,}}/>
{/* <Strikes strike={43000} ce={marketData.nse_fno_banknifty_05012023_43000_ce} pe={marketData.nse_fno_banknifty_05012023_43000_pe}/>
// <Strikes strike={43100} ce={marketData.nse_fno_banknifty_05012023_43100_ce} pe={marketData.nse_fno_banknifty_05012023_43100_pe}/>
// <Strikes strike={43200} ce={marketData.nse_fno_banknifty_05012023_43200_ce} pe={marketData.nse_fno_banknifty_05012023_43200_pe}/>
// <Strikes strike={43300} ce={marketData.nse_fno_banknifty_05012023_43300_ce} pe={marketData.nse_fno_banknifty_05012023_43300_pe}/>
// <Strikes strike={43400} ce={marketData.nse_fno_banknifty_05012023_43400_ce} pe={marketData.nse_fno_banknifty_05012023_43400_pe}/>
// <Strikes strike={43500} ce={marketData.nse_fno_banknifty_05012023_43500_ce} pe={marketData.nse_fno_banknifty_05012023_43500_pe}/> */}
</ScrollView>
</SafeAreaView>
)
}
react-native websocket react-native-flatlist 客户端 数据流

评论

0赞 Fiston Emmanuel 1/6/2023
检查新的解决方案

答:

0赞 Fiston Emmanuel 1/6/2023 #1

如果您要渲染计算量大的 UI 元素(如图表),则为每次新的流数据更新更新 UI 并不费吹灰之力。

理想情况下,解决方案是将流更新反抖动至少 2 秒,以便更新 UI。

function debounce(func, timeout = 2000) {
  let timer;
  return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => {
      func.apply(this, args);
    }, timeout);
  };
}

const CallWebSocket = async () => {
  // Minimum time to update UI for new stream data in milliseconds
  const STREAM_UPDATE_TRESHOLD = 2000;

  const onMessage = (e) => {
    var text = new Response(e.data).text();
    text.then((res) => {
      recieveddata = [];
      var responsedata = res.split("\n");
      for (var i = 0; i < responsedata.length - 2; i++) {
        var tempdata = responsedata[i].split("|");
        recieveddata.push(
          `{index:${i}, name:${tempdata[0]}, value:${tempdata[1]}}`
        );
      }
      //console.log(recieveddata)
    });
  };
  ws.onopen = () => {
    var requestString = "";
    for (var i = 0; i < requestArray.length; i++) {
      if (i == requestArray.length - 1) {
        requestString = requestString + requestArray[i];
      } else {
        requestString = requestString + requestArray[i] + ",";
      }
    }
    ws.send("type=msubscribe&" + requestString + "&columns=20"); // send a message
  };
  ws.onmessage = debounce(onMessage, STREAM_UPDATE_TRESHOLD);
  ws.onerror = (e) => {
    console.log(e.message);
  };
  ws.onclose = (e) => {
    console.log(e.code, e.reason);
  };
};