opentok / opentok-react

React components for OpenTok.js
https://www.npmjs.com/package/opentok-react
MIT License
107 stars 105 forks source link

OTSubscriber doesn’t re-render correctly when `props.stream` changes #60

Open gasi opened 5 years ago

gasi commented 5 years ago

I believe this is the case because OTSubscriber captures props.stream in the constructor onto this.state: https://github.com/opentok/opentok-react/blob/c6683e2b6577809f4a8b9a7bbc7dcf7d66a313e4/src/OTSubscriber.js#L11-L12

This never changes again, i.e. no setState to change this.state.stream.

When componentDidUpdate checks for changes, it only looks at this.state and prevState instead of this.props and prevProps: https://github.com/opentok/opentok-react/blob/c6683e2b6577809f4a8b9a7bbc7dcf7d66a313e4/src/OTSubscriber.js#L34-L37

Patrick-Ullrich commented 5 years ago

I am going to comment on here, because I think my issue might be related to this.

I am trying to call a function when someone left a session. e.g.

  1. otSession.current.state.streams.length == 1
  2. User leaves
  3. otSession.current.state.streams.length == 0.

However, when I pass the otSession (ref to OTSession) to my component, then in the componentDidUpdate hook I see that prevProps.otSession.current.state.streams.length will always == this.props,otSession.current.state.streams.length.

I am assuming the issue might be in the actual library, where streams might be mutated with something like .push() instead of recreated with concat or the spread operator.

EDIT: Solved this need by managing the stream state myself in the component.

componentDidUpdate(prevProps, prevState) {

        if (prevProps && prevProps.otSession && prevProps.otSession.current && prevProps.otSession.current.state && prevProps.otSession.current.state.streams) {
            let newSubscriberCount = prevProps.otSession.current.state.streams.length;
            if (this.state.subscriberCount != newSubscriberCount) {
                if (this.state.subscriberCount > newSubscriberCount) {
                    console.log('person left')
                }
                this.setState({subscriberCount: newSubscriberCount })
            }
        }

    }