Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/426.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 JS和WebSocket进行实时价格更新_Javascript_Reactjs_Websocket_Use Effect - Fatal编程技术网

Javascript 使用React JS和WebSocket进行实时价格更新

Javascript 使用React JS和WebSocket进行实时价格更新,javascript,reactjs,websocket,use-effect,Javascript,Reactjs,Websocket,Use Effect,我正在构建一个简单的网站,它使用websocket从API检索实时价格,并在收到数据时更新UI。我正在使用ReactJS和WebSocket实现这一目的。 以下是我的websocket代码: const WebSocketContext = createContext(null) export {WebSocketContext} const ENDPOINT = ... export default ({children})=>{ let socket; let

我正在构建一个简单的网站,它使用websocket从API检索实时价格,并在收到数据时更新UI。我正在使用ReactJS和WebSocket实现这一目的。 以下是我的websocket代码:

const WebSocketContext = createContext(null)

export {WebSocketContext}

const ENDPOINT = ... 

export default ({children})=>{
    let socket;
    let ws;

    const subscribe = (ticker)=>{
        const payload = {
            'type':'subscribe',
            'symbol': `${ticker}`
        }
        waitForConnection(()=>socket.send(JSON.stringify(payload)))
    }

    const unsubscribe = (ticker)=>{
        const payload = {
            'type':'unsubscribe',
            'symbol': `${ticker}`
        }
        waitForConnection(()=>socket.send(JSON.stringify(payload)))
    }

    if (!socket){
        socket = new WebSocket(ENDPOINT) 

        socket.onopen = ()=> console.log('Connection opened')

        socket.onclose = ()=> console.log('Connection CLosed')

        ws = {
            socket: socket,
            subscribe,
            unsubscribe
        }
    }

    const waitForConnection = (callback)=>{
        if(socket.readyState === 1){
            callback()
        }else {
            setTimeout(()=>{waitForConnection(callback)}, 500)
        }
    }

    return (
        <WebSocketContext.Provider value={ws}>
            {children}
        </WebSocketContext.Provider>
    )

}
const WebSocketContext=createContext(null)
导出{WebSocketContext}
常量端点=。。。
导出默认值({children})=>{
让插座;
让我们来看看;
const subscribe=(股票代码)=>{
常数有效载荷={
'type':'subscribe',
'symbol':`${ticker}`
}
waitForConnection(()=>socket.send(JSON.stringify(有效负载)))
}
const unsubscribe=(股票代码)=>{
常数有效载荷={
“类型”:“取消订阅”,
'symbol':`${ticker}`
}
waitForConnection(()=>socket.send(JSON.stringify(有效负载)))
}
如果(!套接字){
套接字=新的WebSocket(端点)
socket.onopen=()=>console.log('连接已打开')
socket.onclose=()=>console.log('连接已关闭')
ws={
插座:插座,
订阅
退订
}
}
const waitForConnection=(回调)=>{
if(socket.readyState==1){
回调函数()
}否则{
setTimeout(()=>{waitForConnection(回调)},500)
}
}
返回(
{儿童}
)
}
这是我的组件代码:

const TopListItem = ({ticker})=>{
   
    const [stockData, setStockData] = useState()

    const ws = useContext(WebSocketContext)

    // Retrieve stock data like price
    useEffect(()=>{
      
        const subscribe = async ()=> ws.subscribe(ticker)

        const unsubscribe = async () => ws.unsubscribe(ticker)

        subscribe()

        ws.socket.onmessage = (msg)=>{
            const message = JSON.parse(msg.data)
            if(typeof message.data !== 'undefined'){
                // Retrieve symbol
                const symbol = message.data[0].s
                if(symbol===ticker){
                    // Retrieve price
                    const price = message.data[0].p
                    // Update price
                    setStockData(oldData=>({...oldData, price:price}))
                }
            }
        }

        return ()=> unsubscribe()
    },[])

    
    return(
        <div >
                <div >
                    <span className='ticker'>{ticker}</span>
                </div>
                <div>
                    <span>${stockData && stockData.price}</span>
                </div>
        </div>
    )
}

const TopList = ({user})=>{

    const [listItems, setListItems] = useState([])

    ...

    return(
        <div>
            {listItems && listItems.map(stock=>{
                return <TopListItem key={stock.ticker} ticker={stock.ticker} />
            })}
        </div>
    )   
}
export default TopList
constTopListItem=({ticker})=>{
常量[stockData,setStockData]=useState()
const ws=useContext(WebSocketContext)
//检索股票数据,如价格
useffect(()=>{
const subscribe=async()=>ws.subscribe(ticker)
const unsubscribe=async()=>ws.unsubscribe(ticker)
订阅()
ws.socket.onmessage=(msg)=>{
const message=JSON.parse(msg.data)
if(message.data的类型!==“未定义”){
//检索符号
常量符号=消息。数据[0]。s
如果(符号===股票代码){
//收回价格
const price=message.data[0].p
//更新价格
setStockData(oldData=>({…oldData,price:price}))
}
}
}
return()=>unsubscribe()
},[])
返回(
{ticker}
${stockData&&stockData.price}
)
}
常量TopList=({user})=>{
常量[listItems,setListItems]=useState([])
...
返回(
{listItems&&listItems.map(股票=>{
返回
})}
)   
}
导出默认TopList
假设我有3只股票,我想得到它们的价格。对于每个股票,我呈现一个TopListItem组件,在其中更新数据。我遇到的问题是,只有第三个组件更新了价格。只有第三个组件使用setStockData()更新状态。其余的不更新

以下是三个组成部分。只有第三个(SPY)更新了它的价格

为什么会这样? 任何帮助都将不胜感激