I am trying to create slack clone app using React but facing issues after updating react-router-dom
to 6.8.1 I am getting this error in web console:
Uncaught Error: [PRoute] is not a
<Route>
component. All component children of<Routes>
must be a<Route>
or<React.Fragment>
invariant history.ts:480 createRoutesFromChildren components.tsx:571 React 6 createRoutesFromChildren components.tsx:555 Routes components.tsx:389 React 11 workLoop scheduler.development.js:266 flushWork scheduler.development.js:239 performWorkUntilDeadline scheduler.development.js:533
My code
login.js
import './Login.css'
import Button from '@mui/material/Button';
import { auth, provider } from '../../firebase'
import { CometChat } from '@cometchat-pro/chat'
import { cometChat } from '../../app.config'
import { useState } from 'react'
function Login() {
const [loading, setLoading] = useState(false)
const signIn = () => {
setLoading(true)
auth
.signInWithPopup(provider)
.then((res) => loginCometChat(res.user))
.catch((error) => {
setLoading(false)
alert(error.message)
})
}
const loginCometChat = (data) => {
const authKey = cometChat.AUTH_KEY
CometChat.login(data.uid, authKey)
.then((u) => {
localStorage.setItem('user', JSON.stringify(data))
window.location.href = '/'
console.log(u)
setLoading(false)
})
.catch((error) => {
if (error.code === 'ERR_UID_NOT_FOUND') {
signUpWithCometChat(data)
} else {
console.log(error)
setLoading(false)
alert(error.message)
}
})
}
const signUpWithCometChat = (data) => {
const authKey = cometChat.AUTH_KEY
const user = new CometChat.User(data.uid)
user.setName(data.displayName)
user.setAvatar(data.photoURL)
CometChat.createUser(user, authKey)
.then(() => {
setLoading(false)
alert('You are now signed up, click the button again to login')
})
.catch((error) => {
console.log(error)
setLoading(false)
alert(error.message)
})
}
return (
<div className="login">
<div className="login__container">
<img src={'/logo.png'} alt="Slack Logo" />
<h4>Sign in to CometChat</h4>
<p>cometchat.slack.com</p>
<Button onClick={signIn}>
{!loading ? 'Sign In With Google' : <div id="loading"></div>}
</Button>
</div>
</div>
)
}
export default Login`
App.js
//import { createRoot } from 'react-dom/client';
import './App.css'
import React, {Fragment} from 'react';
import Header from './components/Header/Header'
import Sidebar from './components/sidebar/Sidebar'
import Channel from './screens/channel/Channel'
import Login from './screens/login/Login'
import User from './screens/user/User'
import Home from './screens/home/Home'
import Add from './screens/add/Add'
import { useState, useEffect } from 'react'
import {
Routes,
Route,
Navigate,
BrowserRouter,
} from 'react-router-dom'
import { auth } from './firebase'
function App() {
const [isLoggedIn, setIsLoggedIn] = useState(false)
const [isLoaded, setIsLoaded] = useState(false)
const addStructure = (Component, props) => {
return (
<>
<Header />
<main className="app__body">
<Sidebar />
<Component {...props} />
</main>
</>
)
}
const PRoute = ({ element: Element, auth, ...rest }) => (
<Route
{...rest}
render={(props) =>
auth ? (
addStructure(Element, props)
) : (
<Navigate
to={'/login'}
state= { {from: props.location } }
replace
/>
)
}
/>
)
useEffect(() => {
const data = localStorage.getItem('user')
if (data) {
setIsLoggedIn(true)
} else {
auth.onAuthStateChanged((user) => {
if (user) {
setIsLoggedIn(true)
}
})
}
setIsLoaded(true)
}, [])
if (!isLoaded) return null
return (
<BrowserRouter>
<div className="app">
<Fragment>
<Routes>
<PRoute
path="/channels/:id" auth={isLoggedIn} element={<Channel/>}/>
<PRoute path="/users/:id" auth={isLoggedIn} element={<User/>} />
<PRoute path="/add/channel" auth={isLoggedIn} element={<Add/>} />
<Route path="/login">
<Login />
</Route>
<PRoute path="/" auth={isLoggedIn} element={<Home/>} />
</Routes>
</Fragment>
</div>
</BrowserRouter>
)
}
export default App