0

I have this code in render() that opens a websocket and connects to a Rest service.

return (
      <div className="App">  

        <SockJsClient 
          url = 'http://localhost:8610/refresh/'
          topics={['/topic/notification']} 
          onConnect={console.log("Connection established!")} 
          onDisconnect={console.log("Disconnected!")}
          onMessage={(msg) => this.update()}
          debug= {true}
        />

Everything works fine - the only issue with this approach is, that when the UI is rerendered, the application closes the websocket and reopens it again. Nothing breaks, the app just resumes and nothing happens.

Is this operation very resource consuming? Is there any way to tell react not to re-render that portion of code? Should I be worrying at all?

this.update() re-sets an array in my state.

I know shouldComponentUpdate() is what I need, but then I would have to create a new component that does the rerendering, right? I'm confused.

Thanks!

EDIT: This also works (@zavjs's solution is much more cleaner)

componentDidMount(){

  var self = this; // use self to reference this

  var socket = new SockJS("http://192.168.1.139:8610/refresh");
  var stompClient = Stomp.over(socket);
  stompClient.connect({}, function(frame,) {
    console.log('connected: ' + frame);
    stompClient.subscribe('/topic/notification', function(notification) {
      self.update();  // here
    })
  }, function(err) {
    console.log('err', err);
  });

Also here's more about this!

g00glen00b
  • 41,995
  • 13
  • 95
  • 133
Claim
  • 775
  • 3
  • 12
  • 32

1 Answers1

1

Yes, I'd create an intermediary component, to wrap around your SocketJSClient, and condition shouldComponentUpdate to whenever you purposefully want to make that re-render happen (perhaps when a Socket config like url has changed and you need to pass that down, for instance).

class PreventUpdate extends React.Component {
  shouldComponentUpdate = (nextProps) => {
    //set true if a Socket connection config has changed
    //or something that needs to trigger a re-render in the 
    //child component 
    if(this.nextProps.shouldPreventUpdate) {
      return false;
    }
  };

  render() {
    this.props.children;
  }
}

And now you can do:

<PreventUpdate
  shouldPreventUpdate={someDynamicCondition}>
  <SocketJSClient />
<PreventUpdate/>

With this you can pass in an arbitrary flag to prevent update of a component and all its children. I hope it fits you well

zavjs
  • 368
  • 1
  • 9
  • 1
    Awesome this makes sense! I fiddled with it a while and found out that I could just do this `var self = this;` before calling `stompClient.subscribe('http.....') {..}` and reference it as `self.update()` and it also works! – Claim Feb 26 '18 at 13:27