Skip to content

Commit 26ca6bd

Browse files
authored
chore: add useEffectEvent shim to bindings with react 19.2 dev dep (#1944)
### 💡 Overview Adds the new useEffectEvent hook to the bindings from React 19.2 and shim for older react
1 parent c2287de commit 26ca6bd

File tree

8 files changed

+219
-58
lines changed

8 files changed

+219
-58
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@
7070
"eslint": "^9.26.0",
7171
"eslint-plugin-import": "^2.31.0",
7272
"eslint-plugin-react": "^7.37.5",
73-
"eslint-plugin-react-hooks": "^5.2.0",
73+
"eslint-plugin-react-hooks": "^6.1.0",
7474
"globals": "^16.1.0",
7575
"husky": "^9.1.7",
7676
"lint-staged": "^15.5.2",

packages/react-bindings/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
"devDependencies": {
3232
"@rollup/plugin-typescript": "^12.1.2",
3333
"@stream-io/video-client": "workspace:^",
34-
"@types/react": "^19.1.3",
34+
"@types/react": "^19.2.0",
3535
"react": "19.0.0",
3636
"rimraf": "^6.0.1",
3737
"rollup": "^4.40.2",

packages/react-bindings/src/hooks/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as CallStateHooks from './callStateHooks';
2-
2+
export * from './useEffectEvent';
33
export * from './useObservableValue';
44

55
export * from './store';
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import {
2+
useCallback,
3+
useLayoutEffect,
4+
useRef,
5+
useEffectEvent as BuiltInHook,
6+
} from 'react';
7+
8+
function useEffectEventShim<T extends (...args: any[]) => any>(
9+
cb: T,
10+
): (...funcArgs: Parameters<T>) => ReturnType<T> {
11+
const cbRef = useRef(cb);
12+
13+
useLayoutEffect(() => {
14+
cbRef.current = cb;
15+
}, [cb]);
16+
17+
return useCallback((...args: Parameters<T>) => {
18+
const callback = cbRef.current;
19+
return callback(...args);
20+
}, []);
21+
}
22+
23+
export const useEffectEvent = BuiltInHook ?? useEffectEventShim;

packages/react-native-sdk/src/hooks/usePermissionNotification.tsx

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import { CallingState, OwnCapability } from '@stream-io/video-client';
22
import { useCallStateHooks } from '@stream-io/video-react-bindings';
3-
import { useCallback, useEffect } from 'react';
3+
import { useEffect } from 'react';
44
import { Alert } from 'react-native';
55
import { usePrevious } from '../utils/hooks/usePrevious';
6+
import { useEffectEvent } from '@stream-io/video-react-bindings';
67

78
export type PermissionNotificationProps = {
89
/**
@@ -32,13 +33,13 @@ export const usePermissionNotification = (
3233
const previousHasPermission = usePrevious(hasPermission);
3334
const callingState = useCallCallingState();
3435

35-
const showGrantedNotification = useCallback(() => {
36+
const showGrantedNotification = useEffectEvent(() => {
3637
Alert.alert(messageApproved);
37-
}, [messageApproved]);
38+
});
3839

39-
const showRevokedNotification = useCallback(() => {
40+
const showRevokedNotification = useEffectEvent(() => {
4041
Alert.alert(messageRevoked);
41-
}, [messageRevoked]);
42+
});
4243

4344
useEffect(() => {
4445
// Permission state is not reliable before the call is joined,
@@ -51,11 +52,5 @@ export const usePermissionNotification = (
5152
} else if (!hasPermission && previousHasPermission) {
5253
showRevokedNotification();
5354
}
54-
}, [
55-
callingState,
56-
hasPermission,
57-
previousHasPermission,
58-
showGrantedNotification,
59-
showRevokedNotification,
60-
]);
55+
}, [callingState, hasPermission, previousHasPermission]);
6156
};

packages/react-sdk/src/hooks/useEffectEvent.ts

Lines changed: 0 additions & 16 deletions
This file was deleted.

packages/react-sdk/src/wrappers/LivestreamPlayer/LivestreamPlayer.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
LivestreamLayoutProps,
1313
StreamCall,
1414
} from '../../core';
15-
import { useEffectEvent } from '../../hooks/useEffectEvent';
15+
import { useEffectEvent } from '@stream-io/video-react-bindings';
1616

1717
export type LivestreamPlayerProps = {
1818
/**
@@ -53,7 +53,7 @@ export const LivestreamPlayer = (props: LivestreamPlayerProps) => {
5353
const { callType, callId, ...restProps } = props;
5454
const client = useStreamVideoClient();
5555
const [call, setCall] = useState<Call>();
56-
const onError = useEffectEvent(props.onError);
56+
const onError = useEffectEvent(props.onError ?? (() => {}));
5757

5858
useEffect(() => {
5959
if (!client) return;
@@ -69,7 +69,7 @@ export const LivestreamPlayer = (props: LivestreamPlayerProps) => {
6969
});
7070
setCall(undefined);
7171
};
72-
}, [callId, callType, client, onError]);
72+
}, [callId, callType, client]);
7373

7474
if (!call) {
7575
return null;
@@ -116,7 +116,7 @@ const useLivestreamCall = (props: {
116116
const canJoin =
117117
(joinBehavior === 'asap' && canJoinAsap) ||
118118
(joinBehavior === 'live' && canJoinLive);
119-
const onError = useEffectEvent(props.onError);
119+
const onError = useEffectEvent(props.onError ?? (() => {}));
120120

121121
useEffect(() => {
122122
if (call && call.state.callingState === CallingState.IDLE && canJoin) {
@@ -125,7 +125,7 @@ const useLivestreamCall = (props: {
125125
onError(e);
126126
});
127127
}
128-
}, [call, canJoin, onError]);
128+
}, [call, canJoin]);
129129

130130
return call;
131131
};

0 commit comments

Comments
 (0)