简体   繁体   English

无效挂钩调用

[英]Invalid hook call

I am tring to create a video streaming app, and I got an error logging: "Invalid hook call" when i set "{ ready, tracks } = useMicrophoneAndCameraTracks();"我正在尝试创建一个视频流应用程序,但我收到错误记录:当我设置“{ ready, tracks } = useMicrophoneAndCameraTracks();”时出现“Invalid hook call” and client = useClient();和客户端 = useClient();

I tried not calling the hook useMicrophoneAndCameraTracks and useClient, the error wasn't there but the video won't stream.我尝试不调用钩子 useMicrophoneAndCameraTracks 和 useClient,错误不存在,但视频不会流式传输。 Here is my code这是我的代码

Settings.js设置.js

import { createClient, createMicrophoneAndCameraTracks } from "agora-rtc-react";  

const appId = "d13f5075f00d417092285bc8a52f17f2";  
const token = "007eJxTYOjZ/X7lClbPsGXOv7vW/egUYDx+N+WSl9Bzddlf2fyLD5orMKQYGqeZGpibphkYpJgYmhtYGhlZmCYlWySaGqUZmqcZKT+bk9wQyMiwSdaKkZEBAkF8FobcxMw8BgYAbJIfFw=="  


export const config = { mode: "rtc", codec: "vp8", appId: appId, token: token };  
export const useClient = createClient(config);  
export const useMicrophoneAndCameraTracks = createMicrophoneAndCameraTracks();  
export const channelName = "main";  

VideoCall.js VideoCall.js

import { useState, useEffect } from "react";  
import {  
  config,  
  useClient,  
  useMicrophoneAndCameraTracks,  
  channelName,  
} from "./settings.js";  
import { Grid } from "@material-ui/core";  
import Video from "./Video";  
import Controls from "./Controls";  

export default function VideoCall(props) {  
  const { setInCall } = props;  
  const [users, setUsers] = useState([]);  
  const [start, setStart] = useState(false);  
  const client = useClient();  
  const { ready, tracks } = useMicrophoneAndCameraTracks();  

  useEffect(() => {  
    let init = async (name) => {  
      client.on("user-published", async (user, mediaType) => {  
        await client.subscribe(user, mediaType);  
        if (mediaType === "video") {  
          setUsers((prevUsers) => {  
            return [...prevUsers, user];  
          });  
        }  
        if (mediaType === "audio") {  
          user.audioTrack.play();  
        }  
      });  

      client.on("user-unpublished", (user, mediaType) => {  
        if (mediaType === "audio") {  
          if (user.audioTrack) user.audioTrack.stop();  
        }  
        if (mediaType === "video") {  
          setUsers((prevUsers) => {  
            return prevUsers.filter((User) => User.uid !== user.uid);  
          });  
        }  
      });  

      client.on("user-left", (user) => {  
        setUsers((prevUsers) => {  
          return prevUsers.filter((User) => User.uid !== user.uid);  
        });  
      });  

      try {  
        await client.join(config.appId, name, config.token, null);  
      } catch (error) {  
        console.log("error");  
      }  

      if (tracks) await client.publish([tracks[0], tracks[1]]);  
      setStart(true);  
    };  

    if (ready && tracks) {  
      try {  
        init(channelName);  
      } catch (error) {  
        console.log(error);  
      }  
    }  
  }, [channelName, client, ready, tracks]);  
  
  return (  
    <Grid container direction="column" style={{ height: "100%" }}>  
      <Grid item style={{ height: "5%" }}>  
        {ready && tracks && (  
          <Controls tracks={tracks} setStart={setStart} setInCall={setInCall} />  
        )}  
      </Grid>  
      <Grid item style={{ height: "95%" }}>  
        {start && tracks && <Video tracks={tracks} users={users} />}  
      </Grid>  
    </Grid>  
  );  
}  

App.js应用程序.js

import { useState } from "react";  
import { Button } from "@material-ui/core";  
import VideoCall from "./VideoCall";  

function App() {  
  const [inCall, setInCall] = useState(false);  

  return (  
    <div className="App" style={{ height: "100%" }}>  
      {inCall ? (  
        <VideoCall setInCall={setInCall} />  
      ) : (  
        <Button  
          variant="contained"  
          color="primary"  
          onClick={() => setInCall(true)}  
        >  
          Join Call  
        </Button>  
      )}  
    </div>  
  );  
}  
  
export default App;  

Controls.js控件.js

import { useState } from 'react';    
import { useClient } from './settings';  
import { Grid, Button } from '@material-ui/core';  
import MicIcon from '@material-ui/icons/Mic';  
import MicOffIcon from '@material-ui/icons/MicOff';  
import VideocamIcon from '@material-ui/icons/Videocam';  
import VideocamOffIcon from '@material-ui/icons/VideocamOff';  
import ExitToAppIcon from '@material-ui/icons/ExitToApp';  
  
export default function Controls(props) {  
   const client = useClient();  
   const {tracks, setStart, setInCall} = props;  
   const [trackState, setTrackState] = useState({video: true, audio:   true});  
  
   const mute = async(type)=> {  
      if(type === "audio") {  
         await tracks[0].setEnabled(!trackState.audio);  
         setTrackState((ps) => {  
            return {...ps, audio: !ps.audio}  
         })  
      }  
      else if(type === "video") {  
         await tracks[1].setEnabled(!trackState.video);  
         setTrackState((ps) => {  
            return {...ps, video: !ps.video}  
         })  
      }  
   }  
  
   const leaveChannel = async() => {  
      await client.leave();  
      client.removeAllListeners();  
      tracks[0].close();  
      tracks[1].close();  
      setStart(false);  
      setInCall(false);  
   }  
  
   return (  
      <Grid container spacing={2} alignItems='center'>  
         <Grid item>  
            <Button variant="contained" color={trackState.audio ?   "primary" : "secondary"} onclick={() => mute("audio")}>  
            {trackState.audio ? <MicIcon/> : <MicOffIcon/>}  
            </Button>  
         </Grid>  
         <Grid item>  
         <Button variant="contained" color={trackState.video ?   "primary" : "secondary"} onclick={() => mute("video")}>  
            {trackState.video ? <VideocamIcon/> : <VideocamOffIcon/>}  
            </Button>  
         </Grid>  
         <Grid item>  
         <Button variant="contained" color="default" onclick={() =>   leaveChannel()}>  
            Leave <ExitToAppIcon/>  
            </Button>  
         </Grid>  
      </Grid>  
   )  
}  
  

Video.js视频.js

import { AgoraVideoPlayer } from "agora-rtc-react";  
import { Grid } from "@material-ui/core";  
import { useState, useEffect } from "react";  
  
export default function Video(props) {  
  const { users, tracks } = props;  
  const [gridSpacing, setGridSpacing] = useState(12);  
  
  useEffect(() => {  
    setGridSpacing(Math.max(Math.floor(12 / (users.length + 1)), 4));  
  }, [users, tracks]);  
  
  return (  
    <Grid container style={{ height: "100%" }}>  
      <Grid item xs={gridSpacing}>  
        <AgoraVideoPlayer  
          videoTrack={tracks[1]}  
          style={{ height: "100%", width: "100%" }}  
        />  
      </Grid>  
      {users.length > 0 &&  
        users.map((user) => {  
          if (user.videoTrack) {  
            return (  
              <Grid item xs={gridSpacing}>  
                <AgoraVideoPlayer  
                  videoTrack={user.videoTrack}  
                  key={user.uid}  
                  style={{ height: "100%", width: "100%" }}  
                />  
              </Grid>  
            );  
          } else return null;  
        })}  
    </Grid>  
  );  
}  

Without more detailed code, we can't help you.没有更详细的代码,我们帮不了你。 You probably broke a rule regarding react hooks.您可能违反了关于 React Hooks 的规则。

The official docs state the following:官方文档说明如下:

There are three common reasons you might be seeing it:您可能会看到它的三个常见原因:

  1. You might have mismatching versions of React and React DOM.您的 React 和 React DOM 版本可能不匹配。
  2. You might be breaking the Rules of Hooks.你可能违反了 Hooks 规则。
  3. You might have more than one copy of React in the same app.你可能在同一个应用程序中有多个 React 副本。

Read more about it here: https://reactjs.org/warnings/invalid-hook-call-warning.html在这里阅读更多相关信息: https ://reactjs.org/warnings/invalid-hook-call-warning.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 无效的 Hook 调用 - React Hooks - Invalid Hook Call - React Hooks npm-link 库上的钩子调用无效 - Invalid hook call on npm-link library BrowserRouter 运行错误 - 无效挂钩调用 - BrowserRouter Running Error - Invalid Hook Call 使用 react-hook-form 时出现无效的挂钩调用警告 - Invalid Hook Call Warning on using react-hook-form 如何解决 React Native 中的无效钩子调用错误 - How to solve an invalid hook call error in React Native 反应 - 无效的钩子调用。 未捕获的错误:缩小的 React 错误 #321 - React - invalid hook call. Uncaught Error: Minified React error #321 React - 无效的挂钩调用。 钩子只能在 function 组件的内部调用 - React - Invalid hook call. Hooks can only be called inside of the body of a function component 更改代码以使用 UseLocation 而不是 __RouterContext。 我现在有无效的挂机呼叫 - Change code to use UseLocation instead of __RouterContext. I now have Invalid Hook Call 如何在 React 上使用 Material Ui。 收到错误无效的挂钩调用 - How to use Material Ui on React. getting error Invalid Hook call React/Node 应用程序无法在 Chrome 上运行“错误运行模板:不变违规:无效的挂钩调用” - React/Node app not working on Chrome “Error running template: Invariant Violation: Invalid hook call”
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM