Пример простой web панели с "живым" обновлением.
Сегодня давайте рассмотрим пример реализации панели в React с использованием SignalR и Redux.
1. Создадим React-компонент для панели:
import React from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { updatePanelData } from './Actions';
import { HubConnectionBuilder } from '@microsoft/signalr';
const Panel = () => {
const dispatch = useDispatch();
const panelData = useSelector((state) => state.panelData);
// Подключение к SignalR-хабу и обработка обновлений
React.useEffect(() => {
const connection = new HubConnectionBuilder().withUrl('https://localhost:5000/hub').build();
connection.on('PanelDataUpdated', (data) => {
dispatch(updatePanelData(data));
});
connection.start().catch((err) => console.error(err.toString()));
return () => {
connection.stop();
};
}, [dispatch]);
return (
<div className="panel">
<h2>Panel</h2>
<div className="panel-item">
<label>Первое значение : </label>
<span>{panelData.value1}</span>
</div>
<div className="panel-item">
<label>Второе значение : </label>
<span>{panelData.value2}</span>
</div>
<div className="panel-item">
<label>Третье значение : </label>
<span>{panelData.value3}</span>
</div>
</div>
);
};
export default Panel;
2. Создадим Redux-экшены и редюсер:
// actions.js
export const UPDATE_PANEL_DATA = 'UPDATE_PANEL_DATA';
export const updatePanelData = (data) => ({
type: UPDATE_PANEL_DATA,
payload: data,
});
// reducer.js
import { UPDATE_PANEL_DATA } from './actions';
const initialState = {
value1: 0,
value2: 0,
value3: 0,
};
const panelReducer = (state = initialState, action) => {
switch (action.type) {
case UPDATE_PANEL_DATA:
return { ...state, ...action.payload };
default:
return state;
}
};
export default panelReducer;
3. Настроим store и подключим редюсер к приложению:
// store.js
import { createStore, combineReducers } from 'redux';
import panelReducer from './reducer';
const rootReducer = combineReducers({
panelData: panelReducer,
});
const store = createStore(rootReducer);
export default store;
// App.js
import './index.scss';
import { Provider } from 'react-redux';
import store from './Panel/Store';
import Panel from './Panel/Panel';
import SidePanel from './Panel/SidePanel';
function App() {
return (
<div className="App">
<Provider store={store}>
<Panel />
</Provider>
<SidePanel />
</div>
);
}
export default App;
4. Настроим SignalR-соединение на серверной стороне:
public class PanelWorker : BackgroundService
{
private IHubContext hubContext;
private static CancellationTokenSource _cts;
private Random random= new Random();
public PanelWorker(IHubContext hubContext)
{
this.hubContext = hubContext;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_cts = new CancellationTokenSource();
try
{
while (!_cts.Token.IsCancellationRequested)
{
var data = new PanelData()
{
Value1 = random.Next(),
Value2 = random.Next(),
Value3 = random.Next(),
};
await hubContext.Clients.All.SendAsync("PanelDataUpdated", data);
await Task.Delay(1000);
}
}
catch (Exception _) when (_ is Exception or OperationCanceledException or TaskCanceledException)
{
}
finally
{
_cts.Dispose();
}
await Task.CompletedTask;
}
}
public class PanelData
{
public int Value1 { get; set; }
public int Value2 { get; set; }
public int Value3 { get; set; }
}
В этом примере:
1. Компонент Panel использует useSelector для получения текущих значений панели из Redux-хранилища и useDispatch для отправки действия updatePanelData.
2. В useEffect устанавливается SignalR-соединение с хабом /panelHub. При получении события 'PanelDataUpdated' от сервера, действие updatePanelData отправляется в Redux-хранилище, что приводит к обновлению состояния панели и перерисовке компонента.
3. Redux-экшен updatePanelData создает объект действия с типом UPDATE_PANEL_DATA и payload, содержащим обновленные данные панели.
4. Redux-редюсер panelReducer обрабатывает действие UPDATE_PANEL_DATA, обновляя состояние панели в хранилище.
Таким образом, ваше приложение React будет отображать панель, а при получении обновлений от сервера через SignalR, значения в панели будут автоматически обновляться, используя Redux для управления состоянием.
Только полноправные пользователи могут оставлять комментарии. Аутентифицируйтесь пожалуйста, используя сервисы.