Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using hooks causes player reload #58

Open
brizandrew opened this issue Oct 18, 2019 · 2 comments
Open

Using hooks causes player reload #58

brizandrew opened this issue Oct 18, 2019 · 2 comments
Labels
bug Something isn't working help wanted Extra attention is needed

Comments

@brizandrew
Copy link

There's a problem with using this component inside of a functional component that uses hooks for state management. Because of the nature of functional components, when the value of a state hook changes, any anonymous objects or functions are recreated and passed down to the componentDidUpdate of the ReactPlayerLoader, which triggers a reload of the player because this comparison is checking for strict equality (anonymous functions are not strictly equal even if they are functionally the same).

(See below for user-based solution if you're having this same error)

For example, the following code will continuously reload the player and fire the onSuccess function:

const Video = (props) => {
  const [state, updateState] = useState(1);

  useEffect(() => {
    setInterval(() => {
      updateState(i => i + 1);
    }, 2000);
  }, []);

  return (
    <ReactPlayerLoader
      accountId={ACCOUNT_ID}
      playerId={PLAYER_ID}
      videoId={VIDEO_ID}
      onSuccess={() => { console.log('success'); }}
    />
  );
};

I'm not familiar enough with this component's use cases to suggest the best solve for this problem. If this check is necessary you could create a more complex check such as with lodash's isEqual and isEqualWith and compare string representations of functions to ensure that recreated anonymous functions and object are evaluated as equal. For example:

const x = () => { return null; }
const y = () => { return null; }

x === y; // false
x.toString() === y.toString(); // true

Maybe a better way would be to leave reloading the player to explicit calls (i.e. don't reload it when the onSuccess prop changes, make the user call a reload function if that's the desired effect).

User Fix If Your Player is Reloading

All this to say though there is a solution to this problem that doesn't require a code change and I leave that here for any users that find this issue. It's fairly obvious if you understand the problem: don't use anonymous functions or objects.

This can be achieved in a number of ways but here's an example of avoiding anonymous functions by using the React useMemo hook for memoizing objects and the useCallback hook for memoizing functions. These memoized values WILL be evaluated as equal when using strict equality.

Example:

const Video = (props) => {
  const [state, updateState] = useState(1);

  useEffect(() => {
    setInterval(() => {
      updateState(i => i + 1);
    }, 2000);
  }, []);

  const onSuccess = useCallback(() => {
    console.log('success');
  }, []);

  const options = useMemo(() => ({
    aspectRatio: '16:9',
  }), []);

  return (
    <ReactPlayerLoader
      accountId={ACCOUNT_ID}
      playerId={PLAYER_ID}
      videoId={VIDEO_ID}
      onSuccess={onSuccess}
      options={options}
    />
  );
};

Let me know if I can clarify this post in any way.

@misteroneill misteroneill added bug Something isn't working help wanted Extra attention is needed labels Oct 25, 2019
@misteroneill
Copy link
Member

Thanks for the report! I'm not sure anyone will have time to look at this in the near future.

@howells
Copy link

howells commented Jan 20, 2020

I'm facing the same problem, regardless of using useMemo, so for anyone using hooks (i.e. any modern react development) this component seems to be unusable?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

3 participants