I am experiencing a very strange scenario when I am replicating the example here: SDK quickstart - Video call
Here is my final code:
1- AgoraTest.js
import react, { useState } from "react";
import { AgoraRTCProvider, useRTCClient } from "agora-rtc-react";
import AgoraRTC from "agora-rtc-sdk-ng";
import { Button } from "@mui/material";
import { Videos } from "./Videos";
function AgoraTest(){
const client = useRTCClient(AgoraRTC.createClient({ codec: "vp8", mode: "rtc" }));
AgoraRTC.enableLogUpload();
// Set the log output level as INFO
AgoraRTC.setLogLevel(1);
const [channelName, setChannelName] = useState("test");
const [AppID, setAppID] = useState("a71394619e2043f8ae404cd89843e908");
const [token, setToken] = useState("007eJxTYJBhuSpQeXq6VLpOXnm0rco5h/4zifPLYr6xvijT6uYStFRgSDQ3NLY0MTO0TDUyMDFOs0hMNTEwSU6xsLQwMU61NLB4q/4otSGQkaFVQIKJkQECQXwWhpLU4hIGBgA6bBuS");
const [inCall, setInCall] = useState(false);
const toggleInCall = () => {
setInCall(!inCall);
};
return (
<div>
<h1>Agora React Videocall</h1>
{!inCall ?
<Button onClick={toggleInCall}>Join</Button>
: (
<AgoraRTCProvider client={client}>
<Videos channelName={channelName} AppID={AppID} token={token} />
<br /><br /><Button onClick={toggleInCall}>End Call</Button>
</AgoraRTCProvider>
)}
</div>
)
}
export default AgoraTest;
2- Videos
import { VideoCameraFront } from "@mui/icons-material";
import { IconButton } from "@mui/material";
import { useJoin, useLocalCameraTrack, useLocalMicrophoneTrack, usePublish, useRemoteAudioTracks, useRemoteUsers, RemoteUser, LocalVideoTrack, useRemoteVideoTracks } from "agora-rtc-react";
import { } from "reactstrap";
export function Videos({ channelName, AppID, token}) {
const { isLoading: isLoadingMic, localMicrophoneTrack } = useLocalMicrophoneTrack();
const { isLoading: isLoadingCam, localCameraTrack } = useLocalCameraTrack();
const deviceLoading = isLoadingMic || isLoadingCam;
const joinData =useJoin({
appid: AppID,
channel: channelName,
token: token === "" ? null : token,
});
const publishData = usePublish([localMicrophoneTrack, localCameraTrack],!deviceLoading && joinData.isSuccess);
const remoteUsers = useRemoteUsers();
const { audioTracks } = useRemoteAudioTracks(remoteUsers);
audioTracks.map((track) => track.play());
const toggleEnabled = () => {
localCameraTrack.setEnabled(!localCameraTrack.enabled);
}
if (deviceLoading) {
return <div>Loading devices...</div>;
}
if (publishData.isLoading) {
return <div>Getting published...</div>;
}
if (joinData.isLoading) {
return <div>Getting connected...</div>;
}
return (
<div>
<h1>Video Call {joinData.data}</h1>
<div style={{ height: 200, width: 200 }}>
<LocalVideoTrack track={localCameraTrack} play={true}/>
</div>
{remoteUsers.map((user) => (
<div key={user.uid}>
{user.uid}
<div className="vid" style={{ height: 100, width: 100 }} >
{user.hasVideo ? <RemoteUser user={user} playVideo={true} playAudio={true} /> : <div>No Video</div>}
</div>
</div>
))}
<IconButton onClick={toggleEnabled}>{<VideoCameraFront/>}</IconButton>
</div>
);
}
When I plug this in my code, here is the result: 
As you see, the new user (my other laptop) is connected but no video is sent. The same is happening in the other laptop (the local camera works but nothing is sent).
When I look at the agora analytics, we can make the same conclusion: 
It is certainly not the problem with the network. I tried the AgoraUI and all works pretty fine.

I am quite stuck with this. Does anyone have any idea what I missed?
I tried again with the clone and it worked for me as well.
I changed the version of the agora-rtc-react to "2.0.0-beta.0" and now everything works in my code as well.
I think I know what is the issue with recent versions (2.1.0) of agora-rtc-react:
When I use (2.1.0), there are inconsistencies in type conversion.
Both localCameraTrack and localMicrophoneTrack are cast to types from package “agora-rtc-react” rather than from "agora-rtc-sdk-ng".