Применение socket io и React + redux
Прошу указать на ошибки, мною допущенные. Я делаю учебный проект на React+redux с применением socket io (онлайн продажа/аукцион, пользователи и могут покупать/выставлять на торги акции). Сервер на express, в нем хранятся списки пользователей и имеющиеся на торгах акции. Должен быть клиент и админ ОТДЕЛЬНЫМИ компонентами React, ниже привожу код админа где собственно проблема: я не понимаю куда нужно добавлять socket io в компонент. При таком использовании получаю в консоли ошибку "Cannot update during an existing state transition".
App.js - в нем маршрутизация.
import {BrowserRouter, Switch, Route} from "react-router-dom";
import Admin from './components/admin';
import User from './components/user';
import {Auth} from './components/auth';
const INIT = "INIT";
const redux = require('redux');
const Provider = require('react-redux').Provider;
const reducer = require('./redux/reducers');
const store = redux.createStore(reducer);
store.dispatch({
type: INIT,
state: {
broker: null,
isTenderStart: false,
stocks: [],
brokers: []
}
})
class App extends React.Component {
render() {
return (
<Provider store={store}>
<BrowserRouter>
<Switch>
<Route exact path='/' component={Auth}/>
<Route path='/admin' component={Admin}/>
<Route path='/user' component={User}/>
</Switch>
</BrowserRouter>
</Provider>
)
}
}
export default App;
Admin.js
const io = require('socket.io-client');
const connect = require("react-redux").connect;
const actions = require("../redux/actionscreators");
//let socket = io.connect("http://localhost:3030/");
class Admin extends React.Component {
constructor(props) {
super(props);
this.state = {
socket: null,
isTenderStart: false,
currentStockDistribution: "normal",
currentStockId: "0"
}
this.changeDistribution = this.changeDistribution.bind(this);
this.onAuctionStarted = this.onAuctionStarted.bind(this);
//.... не привожу всех функций для краткости
}
changeDistribution = (event) => {
if (this.state.currentStockId >= 0 && this.state.currentStockDistribution)
if (this.state.socket)
this.state.socket.emit("change distribution", {stock_id: this.state.currentStockId, distribution: this.state.currentStockDistribution});
}
// админ по нажатию запускает аукцион
onAuctionStarted() {
if (this.state.socket)
this.state.socket.emit("admin start");
}
onAuctionStop(){
if (this.state.socket)
this.state.socket.emit("admin stop");
}
setStockId = (event) => {
this.setState({currentStockId: parseInt(event.target.value)});
}
setStockDistribution = (event) => {
this.setState({currentStockDistribution: event.target.value})
}
componentDidMount() {
const socket = io.connect('http://localhost:3030');
socket.on("connect", (data) => {
socket.emit("admin Login");
});
socket.on("admin Update", (data) => {
this.props.updateStocks(data.stocks);
this.props.updateBrokers(data.brokers);
});
//.......
socket.on("tender start", (data) => {
this.props.toggleAuction(true);
this.setState({isTenderStart: true});
});
this.setState({socket: socket});
}
render() {
return (
<div className="AdminPage w3-container">
<h1 className="w3-deep-purple">Admin</h1>
<button onClick={this.onAuctionStarted()} disabled={this.state.isTenderStart} className="w3-button w3-teal w3-round">Start tender</button>
<div className="w3-container">
<h4 className="w3-leftbar w3-border-deep-purple w3-padding">Brokers</h4>
<div className="brokersList w3-container">
{this.renderBrokers()} //
</div>
{this.renderStocksList()} //не привел, т.к. в ней лишь по this.props.stocks полученному через сокеты выводится таблица
</div>
</div>
)
}
renderBrokers() {
return <div>{
this.props.brokers.map((broker, i) =>
<div className="w3-container w3-border w3-border-deep-purple w3-margin user-div w3-small">
<h4 className="w3-container w3-deep-purple">Name: {broker.username}</h4>
<div className="w3-container">
<p>Id: {broker.id}</p>
<p>Budget: {broker.budget}</p>
<p>Start balance: {broker.startBalance}</p>
</div>
<div className="w3-container">
<h5>Have Stocks: </h5>
<table className="w3-table-all w3-margin w3-small">
<tr className="w3-gray">
<th>Stock Id</th> <th>Count</th> <th>On Sale</th>
</tr>
{broker.stocks_have.map((stock, j) =>
<tr><td>{stock}</td> <td>{broker.stocks_have_counts[j]}</td> </td></tr>)}
</table>
</div>
<hr></hr>
</div>)
}</div>
}
}
function mapStateToProps(state) {
return {
isTenderStart: state.get("isTenderStart"),
stocks: state.get("stocks"),
brokers: state.get("brokers")
}
}
export default connect(mapStateToProps, actions)(Admin);```