Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to design a ReactJS component that listens to a WebSocket and interacts with CSS animation

A ReactJS component needs to listen for events emitted by a WebSocket.

For each inbound event the component should render a DOM node.

It should then wait for the CSS animation associated with the DOM node to complete, and then remove the DOM node.

This is a sketch of my intended implementation.

Does this approach look workable?

The setTimeout feels horrible.

class MyComponent extends React.PureComponent {
 componentDidMount() {
    this.props.webSocket.on('myEvent', componentDidReceiveEvent)
  }

  componentWillUnmount() {
    this.props.webSocket.off('myEvent', componentDidReceiveEvent)  
  }

  // is this method style valid syntax?
  componentDidReceiveEvent = limit((evt) => {
    this.state.setState((prev, props) => {
      return {
        ...prev,
        inboundEvents: [...prev.events, evt]
      };
      setTimeout(function() {
        // use Array API to remove evt from the 
        // inboundEvents array on this.state
      }, DURATION_OF_CSS_ANIMATION);
    });
  })

  render() {
    return (<div>
      {this.state.events.map(e => <MyNode key={evt.id} />)}
    </div>);
  }
}

MyComponent.propTypes = {
  id: React.PropTypes.string,
  webSocket: React.PropTypes.oneOfType([
    React.PropTypes.bool,
    React.PropTypes.object,
  ]),
};
like image 876
Ben Aston Avatar asked Jul 27 '17 14:07

Ben Aston


2 Answers

If the setTimeout feels hacky (a view I tend to agree with), you could use the transitionend event instead.

The transitionend event is fired when a CSS transition has completed. In the case where a transition is removed before completion, such as if the transition-property is removed or display is set to "none", then the event will not be generated.

Aside from that I don't really see anything wrong with your approach

like image 96
rossipedia Avatar answered Nov 18 '22 23:11

rossipedia


Use Flux

You can add a listener to the websocket in the app launcher (typically App.js / index.js or something similar). When data comes in the websocket, just call the Flux Action that triggers a store update. The React component can have a store listener and know when to update component state & re-render.

like image 33
Dan Esparza Avatar answered Nov 19 '22 01:11

Dan Esparza