I am using switch for redirecting. In navbar there is All post link when user click on it it should load the all post but it is not reloading. I have to manually refresh the page to make it appear the content of all post.
In app.jsx section Navbar
is imported along with routes which is routing to post and the component is <AllPost />
. In Navbar
I have made a <Link to="post">
but when I am clicking on all post it is showing but empty. When I refresh it it start showing me the content.
AllPost.jsx
import React, { useEffect, useState } from "react";
import { db, storage } from "../firebase-config";
import { collection, getDocs, addDoc } from "firebase/firestore";
import { ref, uploadBytesResumable, getDownloadURL } from "firebase/storage";
import Loading from "../components/Loading";
import { withAuthenticationRequired } from "@auth0/auth0-react";
function AllPost() {
const [user, setUser] = useState([]);
const [image, setImage] = useState("");
const [data, setData] = useState({});
const [name, setName] = useState("");
const [description, setDescription] = useState("");
const [estate, setEstate] = useState("");
const [file, setFile] = useState();
const userCollectionRef = collection(db, "posts");
const handleButton = async () => {
await addDoc(userCollectionRef, {
name: name,
description: description,
estate: estate,
image: image,
});
};
useEffect(() => {
const uploadFiles = () => {
const fileName = new Date().getTime() + file.name;
// console.log(fileName);
const storageRef = ref(storage, fileName);
const uploadTask = uploadBytesResumable(storageRef, file);
// Register three observers:
// 1. 'state_changed' observer, called any time the state changes
// 2. Error observer, called on failure
// 3. Completion observer, called on successful completion
uploadTask.on(
"state_changed",
(snapshot) => {
// Observe state change events such as progress, pause, and resume
// Get task progress, including the number of bytes uploaded and the total number of bytes to be uploaded
const progress =
(snapshot.bytesTransferred / snapshot.totalBytes) * 100;
console.log("Upload is " + progress + "% done");
switch (snapshot.state) {
case "paused":
console.log("Upload is paused");
break;
case "running":
console.log("Upload is running");
break;
default:
break;
}
},
(error) => {
console.log(error);
},
() => {
// Handle successful uploads on complete
// For instance, get the download URL: https://firebasestorage.googleapis.com/...
getDownloadURL(uploadTask.snapshot.ref).then((downloadURL) => {
// console.log("File available at", downloadURL);
setImage(downloadURL);
});
}
);
};
file && uploadFiles();
}, [file]);
useEffect(() => {
const getUsers = async () => {
const data = await getDocs(userCollectionRef);
setUser(data.docs.map((doc) => ({ ...doc.data(), id: doc.id })));
// console.log(data);
};
getUsers();
}, []);
return (
<div>
<input
type="file"
onChange={(e) => {
setFile(e.target.files[0]);
}}
/>
<input
type="text"
onChange={(e) => {
setName(e.target.value);
}}
placeholder="estate"
/>
<input
type="text"
onChange={(e) => {
setDescription(e.target.value);
}}
placeholder="description"
/>
<input
type="text"
onChange={(e) => {
setEstate(e.target.value);
}}
placeholder="name"
/>
<button onClick={handleButton}>Click me</button>
<div className="square center-div">
{user.map((item) => {
return (
<div>
<div className="circle-pfp">{item.description}</div>
<h3>{item.estate}</h3>
<h1>{item.name}</h1>
<img src={item.image} alt="" />
</div>
);
})}
</div>
</div>
);
}
// export default withAuthenticationRequired(AllPost, {
// onRedirecting: () => <Loading />,
// });
export default AllPost;
Navbar.jsx
import React from "react";
import { withAuth0 } from "@auth0/auth0-react";
import { Component } from "react";
import "./NavbarStyles.css";
import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";
import AllPost from "./AllPost";
import Dashboard from "./dashboard";
class Navbar extends Component {
state = { clicked: false };
handleClick = () => {
this.setState({ clicked: !this.state.clicked });
};
render() {
const { user, loginWithRedirect, logout, isAuthenticated } =
this.props.auth0;
return (
<>
<Router>
<nav>
<a href="index.html">
<svg
id="logo-16"
width="109"
height="43"
viewBox="0 0 109 43"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
{" "}
<path
d="M64.9315 11.4284C62.1883 8.6852 58.9316 6.5091 55.3475 5.0245C51.7633 3.5399 47.9219 2.7758 44.0424 2.7758C40.1629 2.7758 36.3215 3.5399 32.7373 5.0245C29.1532 6.5091 25.8965 8.6852 23.1533 11.4284L44.0424 32.3174L64.9315 11.4284Z"
class="ccompli1"
fill="#FFD200"
></path>{" "}
<path
d="M44.0686 32.3475C46.8118 35.0907 50.0684 37.2667 53.6526 38.7513C57.2367 40.2359 61.0782 41 64.9577 41C68.837 41 72.679 40.2359 76.263 38.7513C79.847 37.2667 83.104 35.0907 85.847 32.3475L64.9577 11.4584L44.0686 32.3475Z"
class="ccompli2"
fill="#06E07F"
></path>{" "}
<path
d="M44.017 32.3429C41.2738 35.0861 38.0171 37.2621 34.433 38.7467C30.8488 40.2313 27.0074 40.9954 23.1279 40.9954C19.2484 40.9954 15.407 40.2313 11.8228 38.7467C8.2387 37.2621 4.982 35.0861 2.2388 32.3429L23.1279 11.4538L44.017 32.3429Z"
class="ccustom"
fill="#E3073C"
></path>{" "}
<path
d="M64.9831 11.433C67.726 8.6898 70.983 6.5138 74.567 5.0292C78.151 3.5446 81.993 2.7805 85.872 2.7805C89.752 2.7805 93.593 3.5446 97.177 5.0292C100.761 6.5138 104.018 8.6898 106.761 11.433L85.872 32.3221L64.9831 11.433Z"
class="ccustom"
fill="#1F84EF"
></path>{" "}
</svg>
</a>
<div>
<ul
id="navbar"
className={this.state.clicked ? "#navbar active" : "#navbar"}
>
<Link to="post">All Post</Link>
{isAuthenticated && (
<li>
<p className="para">Welcome , {user.name}</p>
</li>
)}
{isAuthenticated ? (
<li>
<button
onClick={() =>
logout({
logoutParams: { returnTo: window.location.origin },
})
}
>
Log Out
</button>
</li>
) : (
<li>
<button onClick={() => loginWithRedirect()}>Log In</button>
</li>
)}
</ul>
</div>
<div id="mobile" onClick={this.handleClick}>
<i
id="bar"
className={this.state.clicked ? "fas fa-times" : "fas fa-bars"}
></i>
</div>
</nav>
</Router>
</>
);
}
}
export default withAuth0(Navbar);
App.jsx
import "./App.css";
import Navbar from "./components/Navbar";
import { Router, Route, Switch } from "react-router-dom";
import { Footer } from "./components/Footer";
import Dashboard from "./components/dashboard";
import { useAuth0 } from "@auth0/auth0-react";
import { createBrowserHistory } from "history";
import { HeroText } from "./components/hero";
import Loading from "./components/Loading";
import { Profile } from "./components/profile";
import AllPost from "./components/AllPost";
const history = createBrowserHistory();
function App() {
const { isLoading, error, isAuthenticated } = useAuth0();
if (error) {
return <div>Oops... {error.message}</div>;
}
if (isLoading) {
return <Loading />;
}
return (
<Router history={history}>
<Navbar />
<Switch>
<Route
path="/"
exact
component={isAuthenticated ? Dashboard : HeroText}
/>
<Route path="/post" component={AllPost} />
<Route path="/profile" component={Profile} />
<Route
path="*"
component={() => {
return <div>404 , PAGE NOT FOUND</div>;
}}
/>
</Switch>
<Footer />
</Router>
);
}
export default App;
The app is rendering more than one router component, one in App
and another in Navbar
. When a link in Navbar
is clicked the BrowserRouter
that Navbar
renders handles the navigation action, i.e. it updates the URL to the target path. The Router
rendered by App
is never aware of this handled navigation action lower down the ReactTree. In other words, each router functions and operates independently and don't share any context or information elsewhere for the navigation actions they effect/handle. The outer Router
in App
doesn't "see" the new path until the page is reloaded and all routers mount again and check the URL path to see what they should match and render.
You need only one router to provide a routing context to the entire app, so remove one of them. I suggest removing the extraneous router that Navbar
is rendering so it receives and accesses the routing context provided by the Router
that App
renders.
Example:
class Navbar extends Component {
state = { clicked: false };
handleClick = () => {
this.setState(prevState => ({
clicked: !prevState.clicked
}));
};
render() {
const {
user,
loginWithRedirect,
logout,
isAuthenticated
} = this.props.auth0;
return (
<nav>
<a href="index.html">
<svg
id="logo-16"
width="109"
height="43"
viewBox="0 0 109 43"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
...
</svg>
</a>
<div>
<ul
id="navbar"
className={this.state.clicked ? "#navbar active" : "#navbar"}
>
<Link to="post">All Post</Link>
{isAuthenticated && (
<li>
<p className="para">Welcome , {user.name}</p>
</li>
)}
{isAuthenticated ? (
<li>
<button
onClick={() =>
logout({
logoutParams: { returnTo: window.location.origin },
})
}
>
Log Out
</button>
</li>
) : (
<li>
<button onClick={() => loginWithRedirect()}>Log In</button>
</li>
)}
</ul>
</div>
<div id="mobile" onClick={this.handleClick}>
<i
id="bar"
className={this.state.clicked ? "fas fa-times" : "fas fa-bars"}
></i>
</div>
</nav>
);
}
}
export default withAuth0(Navbar);
function App() {
const { isLoading, error, isAuthenticated } = useAuth0();
if (error) {
return <div>Oops... {error.message}</div>;
}
if (isLoading) {
return <Loading />;
}
return (
<Router history={history}> // <-- Provides routing context
<Navbar /> // <-- Accesses routing context
<Switch>
<Route
path="/"
exact
component={isAuthenticated ? Dashboard : HeroText}
/>
<Route path="/post" component={AllPost} />
<Route path="/profile" component={Profile} />
<Route
path="*"
render={() => {
return <div>404 , PAGE NOT FOUND</div>;
}}
/>
</Switch>
<Footer />
</Router>
);
}