Claim
Claim

Reputation: 921

Stop React from rendering code that opens websockets

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!

Upvotes: 1

Views: 1392

Answers (1)

zavjs
zavjs

Reputation: 378

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

Upvotes: 1

Related Questions