I’ve used routes to update props in my same component,
but on clicking the buttons only links change in the url but no routing happens in the webpage, after reloading it works fine.
App.js:
import './App.css';
import React, { Component } from 'react'
import Navbar from './components/Navbar'
import News from './components/News';
import {
BrowserRouter as Router,
Routes,
Route,
} from "react-router-dom";
export default class App extends Component {
render() {
return (
<>
<Navbar/>
<Router>
<Routes>
<Route exact path="/" element={<News key={"1"} country={"in"} category="general" pageSize={6}/>} />
<Route exact path="/general" element={<News key={"2"} country={"in"} category="general" pageSize={6}/>} />
<Route exact path="/business" element={<News key={"3"} country={"in"} category="business" pageSize={6}/>} />
<Route exact path="/entertainment" element={<News key={"4"} country={"in"} category="entertainment" pageSize={6}/>} />
<Route exact path="/health" element={<News key="health" country={"in"} category="health" pageSize={6}/>} />
<Route exact path="/science" element={<News key="science" country={"in"} category="science" pageSize={6}/>} />
<Route exact path="/sports" element={<News key="sports" country={"in"} category={"sports"} pageSize={6}/>} />
<Route exact path="/technology" element={<News key="technology" country={"in"} category={"technology"} pageSize={6}/>} />
<Route exact path="/education" element={<News key="education" country={"in"} category={"education"} pageSize={6}/>} />
</Routes>
</Router>
</>
)
}
}
News.js:
import Loading from './Loading';
import NewsItem from './NewsItem'
import React, { Component } from 'react'
export default class News extends Component {
constructor() {
super()
this.state = {
articles: [],
loading: false,
page: 1,
totalResults: 0
}
}
async componentDidMount() {
var url = `https://newsapi.org/v2/top-headlines?country=${this.props.country}&category=${this.props.category}&apiKey=71af8e98db3b4e04b13dcfaca6f9ee2a&page=${this.state.page + 1}&pageSize=${this.props.pageSize}`;
this.setState({ loading: true })
var data = await fetch(url);
let parsedData = await data.json();
console.log(parsedData);
this.setState({
articles: parsedData.articles,
totalResults: parsedData.totalResults,
loading: false
});
}
handleNext = async () => {
console.log("next");
console.log(this.state.totalResults, this.state.page);
if ((this.state.page + 1) > Math.ceil(this.state.totalResults / 6)){
} else {
var url = `https://newsapi.org/v2/top-headlines?country=${this.props.country}&category=${this.props.category}&apiKey=71af8e98db3b4e04b13dcfaca6f9ee2a&page=${this.state.page + 1}&pageSize=${this.props.pageSize}`;
this.setState({ loading: true });
var data = await fetch(url);
let parsedData = await data.json();
console.log(parsedData);
this.setState({
articles: parsedData.articles,
page: this.state.page + 1,
loading: false
});
}
}
handlePrev = async () => {
console.log("previous");
var url = `https://newsapi.org/v2/top-headlines?country=${this.props.country}&category=${this.props.category}&apiKey=71af8e98db3b4e04b13dcfaca6f9ee2a&page=${this.state.page + 1}&pageSize=${this.props.pageSize}`;
this.setState({ loading: true });
var data = await fetch(url);
let parsedData = await data.json();
console.log(parsedData);
this.setState({
articles: parsedData.articles,
page: this.state.page - 1,
loading: false
});
}
render() {
return (
<>
<div className="container my-3">
<h1 className='text-center my-5'>Top News Headlines :</h1>
{this.state.loading && <Loading/>}
<div className="row my-3">
{!this.state.loading && this.state.articles.map((element) => {
return <div className="col" key={element.url}>
<NewsItem imageurl={element.urlToImage} title={element.title} description={element.description} author={element.author} time={element.publishedAt} />
</div>
})}
</div>
</div>
<div className="container d-flex justify-content-around my-5">
<button disabled={this.state.page<=1} type="button" onClick={this.handlePrev} className="btn btn-primary">←Previous </button>
<button disabled={(this.state.page + 1) > Math.ceil(this.state.totalResults/6)} type="button" onClick={this.handleNext} className="btn btn-primary">Next →</button>
</div>
</>
)
}
}
Navbar.js:
import React, { Component } from 'react'
import { BrowserRouter, Link } from "react-router-dom";
export default class Navbar extends Component {
render() {
return (
<>
<BrowserRouter>
<nav className="navbar navbar-expand-lg bg-body-tertiary" data-bs-theme="dark">
<div className="container-fluid ">
<Link className="navbar-brand" to="/">News Letter</Link>
<button className="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span className="navbar-toggler-icon"></span>
</button>
<div className="collapse navbar-collapse" id="navbarSupportedContent">
<ul className="navbar-nav me-auto mb-2 mb-lg-0">
<li className="nav-item"> <Link to="/general" className="nav-link" >Home</Link></li>
<li className="nav-item"> <Link to="/business" className="nav-link">Business</Link></li>
<li className="nav-item"> <Link to="/entertainment" className="nav-link">Entertainment</Link></li>
<li className="nav-item"> <Link to="/health" className="nav-link">Health</Link></li>
<li className="nav-item"> <Link to="/science" className="nav-link">Science</Link></li>
<li className="nav-item"> <Link to="/sports" className="nav-link">Sports</Link></li>
<li className="nav-item"> <Link to="/technology" className="nav-link">Technology</Link></li>
<li className="nav-item"> <Link to="/education" className="nav-link">Education</Link></li>
</ul>
</div>
</div>
</nav>
</BrowserRouter>
</>
)
}
}
I tried routing and update page content but only url changed.
2
Answers
We have some usage order issues.
Correct usage:
Remove ‘BrowserRouter’ from your Navbar.js and up it to App.js
You are rendering different parts of your UI into different routers. Routers don’t share any state or information. What happens in one router, e.g. clicking a link, isn’t made available to any other router the app may be rendering.
You need only one router per app to provide the same single routing context to all routes, links, hooks, etc. Remove the
BrowserRouter
fromNavbar
and promote theBrowserRouter
inApp
to wrap around both theNavbar
and theRoutes
.Example:
Navbar
App