简体   繁体   中英

Trigger React onChange event with JS/jQuery

I'm trying to update the state in a React component when data is received from a WebSocket connection.

I've created a hidden input form, where when it's changed will trigger the state to update and the component will automatically update based on the data stored inside the state.

I originally tried to trigger the React event with .change() which wasn't working, turns out you can't actually trigger React events using jQuery as the events aren't actually proper DOM events. so then I tried actually setting the value of the input to the data sent from the WebSocket, which didn't work either (data can be received every second - sometimes even quicker).

If I set the input to text and start typing, then the component updates correctly. But I need it to update whenever data is received from the server.

Here's my attempt so far:

class MyTable extends React.Component {
  constructor(props) {
    super(props);
    this.state = { data: parsedTradeData };
    this.handleChange = this.handleChange.bind(this);
    console.log("constructed")
  }
  handleChange(event) {
    console.log("changed")
    this.setState({ data: makeData() });
  }
  componentWillReceiveProps(nextProps) {
    console.log("next props")
    console.log(nextProps)
  }
  render() {
    return (
      <div>
        <input type="hidden" className="trade-table-data-input" onChange={ this.handleChange } />
        {this.drawTable()}
      </div>
    );
  }
  drawTable() {
    return React.createElement('div', null, React.createElement(ReactTable, {
            data: this.state.data,
            columns: columns,
            defaultPageSize: 25,
            showPagination: true,
            className: '-striped -highlight table',
            SubComponent: function SubComponent(row) {
                tradeDetailsID = row['row']['id'];

                tradeDetailsConnection = new WebSocket('ws://kieron-pc:8080/request');

                tradeDetailsConnection.onopen = function() {
                    var args = [
                        sessionID,
                        $('#acc_select option:selected').val(),
                        pageID,
                        '15',
                        'TradeDetails',
                        row['row']['id']
                    ];

                    tradeDetailsConnection.send(args.join(','));

                    tradeDetailsConnection.onmessage = function(event) {
                        var dataReceived = event.data.split(',').slice(6).join(',');
                        var requestType = JSON.parse(event.data.split(',')[6] + "}")['id'];

                        data["TradeDetails" + requestType] = dataReceived;
                    }
                }

                return React.createElement("div", { className: "container" }, React.createElement("div", { className: "row" }, React.createElement("div", { className: "col-md-6" }, React.createElement('h5', null, 'Summary'), React.createElement('div', null, React.createElement(ReactTable, {
                            data: makeTradeDetailsSummaryData(row['row']['id']),
                            columns: tradeDetailsSummaryColumns,
                            defaultPageSize: 5,
                            showPagination: false
                        })), React.createElement("h5", null, "Costs"), React.createElement('div', null, React.createElement(ReactTable, {
                            data: makeTradeDetailsCostsData(row['row']['id']),
                            columns: tradeDetailsCostsColumns,
                            defaultPageSize: 4,
                            showPagination: false
                        }))), React.createElement("div", { className: "col-md-6" }, React.createElement("p", null, "chart")), React.createElement("div", { className: "col-md-12" }, React.createElement("h5", null, "Daily Breakdown"), React.createElement("h5", null, "Executions"), React.createElement('div', null, React.createElement(ReactTable, {
                            data: makeTradeDetailsExecutionsData(row['row']['id']),
                            columns: tradeDetailsExecutionsColumns,
                            defaultPageSize: 4,
                            showPagination: false
                        })))));
            },
            defaultSortMethod: function defaultSortMethod(a, b) {
                a = a === null || a === undefined ? '' : a;
                b = b === null || b === undefined ? '' : b;

                if (isNaN(a) && isNaN(b)) {
                    a = a.toLowerCase();
                    b = b.toLowerCase();

                    if (a > b) {
                        return 1;
                    }

                    if (a < b) {
                        return -1;
                    }

                    return 0;
                } else {
                    return a - b;
                }
            },
            getTrProps: function getTdProps(state, rowInfo, column) {
                return {
                    onClick: function onClick(e) {
                        if (expands[rowInfo.index] == true) {
                            expands[rowInfo.index] = false;
                        } else {
                            expands[rowInfo.index] = true;
                        }
                    }
                };
            }
        }));
  }
}

Thanks

This code looks too imperative. One of the main React's point is declarativity. You can create elements by React.createElement but you should not.

To split up logic and view in your case you can move the "socket code" to a High Order Component ( https://facebook.github.io/react/docs/higher-order-components.html ).

In it you can make all your socket magic and pass it to wrapped component as props. All changes will be applied automatically.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM