如何修复 React Native Agora 异步错误

Posted

技术标签:

【中文标题】如何修复 React Native Agora 异步错误【英文标题】:How to fix React Native Agora asynchronous error 【发布时间】:2020-12-18 01:57:56 【问题描述】:

我收到了这个 Eslint 错误:

从 React Hook useCallback 内部对 '_engine' 变量的分配将在每次渲染后丢失。要随着时间的推移保留该值,请将其存储在 useRef Hook 中,并将可变值保留在 '.current' 属性中。否则,你可以直接在 useCallback.eslint(react-hooks/exhaustive-deps) 中移动这个变量

从此代码:

  const RtcEngineInit = useCallback(async () => 
    const appId = appInit;
    _engine = await RtcEngine.create(appId);

    await _engine.enableAudio();

    _engine.addListener('UserOffline', (uid: any, reason: any) => 
      console.log('UserOffline', uid, reason);
      const peerIds = appInit;
      setAppInit((prevState) => (
        ...prevState,
        peerIds: peerIds.filter((id) => id !== uid),
      ));
    );

    _engine.addListener(
      'JoinChannelSuccess',
      (channel: any, uid: any, elapsed: any) => 
        console.log('JoinChannelSuccess', channel, uid, elapsed);

        setAppInit((prevState) => (
          ...prevState,
          joinSucceed: true,
        ));
      ,
    );
  , []);

  React.useEffect(() => 
    RtcEngineInit();
  , [RtcEngineInit]);

有人可以解释一下为什么会发生这种情况并帮助我解决这个问题吗?谢谢。

【问题讨论】:

【参考方案1】:

正如错误所暗示的,您不应该在渲染循环中使用 RTC 引擎。渲染循环中的所有语句都会再次执行。为了避免这种情况。您可以将 RTC 引擎放在 useRef 挂钩中。

const App: React.FC = () => 
  let engine = useRef<RtcEngine | null>(null);

  const appid: string = 'APPID';
  const channelName: string = 'channel-x';
  const [joinSucceed, setJoinSucceed] = useState<boolean>(false);
  const [peerIds, setPeerIds] = useState<Array<number>>([]);

  useEffect(() => 
    /**
     * @name init
     * @description Function to initialize the Rtc Engine, attach event listeners and actions
     */
    async function init() 
      if (Platform.OS === 'android') 
        //Request required permissions from Android
        await requestCameraAndAudioPermission();
      
      engine.current = await RtcEngine.create(appid);
      engine.current.enableVideo();

      engine.current.addListener('UserJoined', (uid: number) => 
        //If user joins the channel
        setPeerIds((pids) =>
          pids.indexOf(uid) === -1 ? [...pids, uid] : pids,
        ); //add peer ID to state array
      );

      engine.current.addListener('UserOffline', (uid: number) => 
        //If user leaves
        setPeerIds((pids) => pids.filter((userId) => userId !== uid)); //remove peer ID from state array
      );

      engine.current.addListener('JoinChannelSuccess', () => 
        //If Local user joins RTC channel
        setJoinSucceed(true); //Set state variable to true
      );
    
    init();
  , []);

  
  return <UI />
;

export default App;

完整示例位于: https://github.com/technophilic/Agora-RN-Quickstart/blob/sdk-v3-ts/src/App.tsx

【讨论】:

以上是关于如何修复 React Native Agora 异步错误的主要内容,如果未能解决你的问题,请参考以下文章

Agora React-native 语音通话

Agora.io React-native 课堂和白板集成

agora.io react-native setEnableSpeakerphone 花费了太多时间

RtcEngine 使用从 React Native Agora 中的服务生成的令牌加入 Channel

Agora React Native 麦克风权限

使用 agora.io 发布流