如何在 React 中处理多个 websocket 订阅?
How to handle multiple websocket subscriptions in React?
我使用 websocket API 订阅了几个符号,例如 BTC-USD 和 EUR-USD。
响应以混合在消息流中的持续对象流(例如 {symbol: 'EUR-USD', price: '1.1'})的形式出现:一些带有 EUR-USD 的价格,一些带有BTC-USD 的价格。
我想在 table 中显示值。我该怎么做?
我想到了下面的东西(它不起作用):
this.socket.addEventListener('message', (e) => {
e.data.symbol === 'EUR-USD' && this.setState({ pairEURUSD: JSON.parse(e.data) });
e.data.symbol === 'BTC-USD' && this.setState({ pairBTCUSD: JSON.parse(e.data) });
});
然后在渲染方法中显示适当的状态对。
我还在渲染方法中想到了以下内容(它有点管用):
<p>{this.state.pair === 'BTC-USD' && this.state.pair.price}</p>
<p>{this.state.pair === 'EUR-USD' && this.state.pair.price}</p>
如果最新的输出消息是针对 BTC-USD 对,则这不会为 EUR-USD 呈现任何内容。我显然想渲染一些东西,最新的值,而一对没有更新的值。
关于如何在函数或 class 组件中或(可能更好)使用 redux-saga 实现的任何建议?
代码不多,但我认为您的想法是正确的。您可能只是对 reading/writing 状态有误。
如果你想使用 sagas,你首先需要 eventChannel
实用程序来包装监听器。
import {eventChannel} from 'redux-saga'
const socketChannel = eventChannel((emit) => {
socket.addEventListener('message', emit)
return () => socket.removeEventListener('message', emit)
})
然后您可以像对 redux 操作一样在该频道上使用 take
效果:
yield takeEvery(socketChannel, function* (message) {
const {symbol, price} = JSON.parse(message.data)
yield put(storeNewValue(symbol, price))
})
之后就是 react/reducer 数据的正常 react/reducer 逻辑,例如
// reducer
...
case STORE_NEW_VALUE:
return {
...state,
[action.symbol]: action.price,
}
...
// react
const ItemTable = () => {
const data = useSelector(state => state.path.to.data)
const rows = Object.entries(data).map(([symbol, price]) => (
<div>{symbol + ' ' + price}</div>
))
return <div>{rows}</div>
}
在此处查看工作演示:
https://codesandbox.io/s/dt8us?file=/src/index.js
我使用 websocket API 订阅了几个符号,例如 BTC-USD 和 EUR-USD。 响应以混合在消息流中的持续对象流(例如 {symbol: 'EUR-USD', price: '1.1'})的形式出现:一些带有 EUR-USD 的价格,一些带有BTC-USD 的价格。
我想在 table 中显示值。我该怎么做?
我想到了下面的东西(它不起作用):
this.socket.addEventListener('message', (e) => {
e.data.symbol === 'EUR-USD' && this.setState({ pairEURUSD: JSON.parse(e.data) });
e.data.symbol === 'BTC-USD' && this.setState({ pairBTCUSD: JSON.parse(e.data) });
});
然后在渲染方法中显示适当的状态对。
我还在渲染方法中想到了以下内容(它有点管用):
<p>{this.state.pair === 'BTC-USD' && this.state.pair.price}</p>
<p>{this.state.pair === 'EUR-USD' && this.state.pair.price}</p>
如果最新的输出消息是针对 BTC-USD 对,则这不会为 EUR-USD 呈现任何内容。我显然想渲染一些东西,最新的值,而一对没有更新的值。
关于如何在函数或 class 组件中或(可能更好)使用 redux-saga 实现的任何建议?
代码不多,但我认为您的想法是正确的。您可能只是对 reading/writing 状态有误。
如果你想使用 sagas,你首先需要 eventChannel
实用程序来包装监听器。
import {eventChannel} from 'redux-saga'
const socketChannel = eventChannel((emit) => {
socket.addEventListener('message', emit)
return () => socket.removeEventListener('message', emit)
})
然后您可以像对 redux 操作一样在该频道上使用 take
效果:
yield takeEvery(socketChannel, function* (message) {
const {symbol, price} = JSON.parse(message.data)
yield put(storeNewValue(symbol, price))
})
之后就是 react/reducer 数据的正常 react/reducer 逻辑,例如
// reducer
...
case STORE_NEW_VALUE:
return {
...state,
[action.symbol]: action.price,
}
...
// react
const ItemTable = () => {
const data = useSelector(state => state.path.to.data)
const rows = Object.entries(data).map(([symbol, price]) => (
<div>{symbol + ' ' + price}</div>
))
return <div>{rows}</div>
}
在此处查看工作演示: https://codesandbox.io/s/dt8us?file=/src/index.js