如何在React组件中更新信号数据



我正在测试将从json端点获取数据的组件转换为从操作仪表板的信号端点获取连续更新。我在博客和SO上读到的是,在2021年我们应该使用@microsoft/signalr在反应端与信号端点通信。

下面是我的测试代码,它从signalr端点接收数据并更新组件的状态,但是ShimmeredDetailsList不会用数据重新绘制。建议/批评在这里需要改变什么以每隔30秒更新一次数据?也许我的结构不正确。对信号的读数有什么建议吗?我们正在尝试只使用office-ui-fabric-react组件。

import React, { Component } from 'react';
import {
Fabric,
SelectionMode,
ShimmeredDetailsList,
Panel,
PanelType,
Stack,
StackItem,
mergeStyleSets,
Selection,
} from 'office-ui-fabric-react';
import { HubConnectionBuilder, HubConnectionState } from '@microsoft/signalr';
export class AccountsList extends Component {
displayName = AccountsList.name;
constructor(props) {
super(props);
this.componentDidMount = this.componentDidMount.bind(this);
this.dismiss = this.dismiss.bind(this);
this.onSelectionChange = this.onSelectionChange.bind(this);
this.selection = new Selection({
onSelectionChanged: () => this.onSelectionChange(),
});
this.state = {
items: [],
selectedItem: {},
panelOpen: false,
loaded: false,
appId: '',
};
}
componentDidMount() {
/*
fetch('/api/Accounts/Accounts')
.then(response => response.json())
.then(data => { this.setState({ items: data, loaded: true }) });
*/
this.setUpSignalRConnection().then(() => {
this.forceUpdate();
});
}
async setUpSignalRConnection() {
const connection = new HubConnectionBuilder().withUrl('/api/DashboardHub').withAutomaticReconnect().build();
connection.on('Message', (message: string) => {
console.log('signalr: message : ' + message);
});
connection.on('Accounts', (data) => {
if (data != null) {
this.setState({ items: data, loaded: true });
console.log(this.state.items);
}
});
try {
await connection.start();
console.log('signalr connection state: ' + connection.state);
connection.invoke('GetAccounts');
} catch (err) {
console.log('signalr: error : ' + err);
}
}
columns = [
{ key: 'name', name: 'Name', fieldName: 'name', minWidth: 100, maxWidth: 200, isResizeable: true },
{
key: 'currentBalance',
name: 'Current Balance',
fieldName: 'currentBalance',
minWidth: 100,
maxWidth: 400,
isResizeable: true,
},
{
key: 'maxBuyingPower',
name: 'Buying Power',
fieldName: 'maxBuyingPower',
minWidth: 100,
maxWidth: 400,
isResizeable: true,
},
];
styles = mergeStyleSets({
stackRoot: {
height: '100%',
},
header: {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
},
content: {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
padding: 10,
},
});
dismiss() {
this.setState({ panelOpen: false });
}
onSelectionChange() {
if (!this.selection) {
return;
}
const selectedItem = this.selection.getSelection()[0];
if (selectedItem) {
//this.setState({ selectedItem: selectedItem, panelOpen: true });
}
}
render() {
return (
<Fabric>
<ShimmeredDetailsList
setKey="set"
items={this.state.items}
enableShimmer={!this.state.loaded}
columns={this.columns}
selectionMode={SelectionMode.single}
selection={this.selection}
/>
<Panel isOpen={this.state.panelOpen} type={PanelType.medium} isLightDismiss="true" onDismiss={this.dismiss}>
<Stack vertical className={this.styles.stackRoot}>
<StackItem></StackItem>
<br />
<StackItem grow></StackItem>
</Stack>
</Panel>
</Fabric>
);
}
}

所以,我也有点新的,但最近我设法使用信号为我的一个项目。我在网上读了一些文章,是的,你需要在你的react应用程序上使用asp.net Core和@microsoft/signalr。

在我的项目中,我设法使它工作与信号没有jQuery,但在我的后端项目,我使用asp.net框架。

还有,我不明白你为什么要每30秒就提出一个请求。signalr的特点是,当某些东西根据你的需要得到更新时,它会自动发送请求。例如,如果您的一个react客户端将发送消息,该消息将转到API,然后服务器将为所有用户发送消息。

我的代码示例:

let connection = new 
hubConnection('https://localhost:
44384/signalr/hubs');
let hubProxy = 
connection.createHubProxy('HubSignalR');
let hubProxy = 
connection.createHubProxy('HubSignalR');
hubProxy.on('pushNewElement', 
function(message) {
console.log(message);
});
console.log(hubProxy);
connection.start({ jsonp: true ,    transport: 
['webSockets'], useDefaultPath: false 
})
.done(function(){ console.log('Now connected, 
connection ID=' + connection.id);
hubProxy.invoke('SendElement',  "hey!" 
).done(function  () {
console.log ('Invocation succeeded');
}).fail(function (error) {
console.log('Invocation failed. Error: ' + 
error);
});
})
.fail(function(){ console.log('Could not 
connect'); });
console.log(connection);

connection.disconnected(function () {
// Try to reconnect after 5 seconds
setTimeout(function () {

connection.start({ jsonp: true , transport: [ 
'webSockets'] })
.done(function(){ console.log('Now 
connected, connection ID=' + connection.id);
})
.fail(function(){ console.log('Could not 
connect'); });
}, 5000);
});

hubProxy.on()是服务器发送回消息时将执行的函数。此外,'pushNewElement'需要与您的集线器完全相同,否则它将无法工作。

hubProxy.invoke()是将消息发送到服务器的函数,所以如果你在组件类之前声明你的连接和hubproxy,你可以在组件类的任何其他函数中使用它。此外,invoke('myFunc',…)中的字符串必须与您的API中的字符串相同。

在c#:

[HubName("HubSignalR")]
public class HubSignalR : Hub
{
[HubMethodName("SendElement")]
public void SendElement(string message)
{
IHubContext context = 
GlobalHost.ConnectionManager.
GetHubContext("HubSignalR");
context.Clients.All.pushNewElement(message);
}
}

最新更新