In real word example, There is lots of routes in web page which is handled by Server. Of course, we should show different visual content of each paths.
We still want to build Sinlge Page App in react. With that reason, we will handle path changes with react-code and change visible content as to those paths without fetching a new HTML file like vanilla javascript web page.
npm install react-router-dom
The process will be like this :
domain.com/products -> components related to products
domain.com/contacts -> components related to contacts
and so on.
We will render each components according to routes.
import ReactDOM from "react-dom";
import { BrowserRouter } from "react-router-dom";
import "./index.css";
import App from "./App";
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById("root")
);
import { Route } from "react-router-dom";
<Route path="/welcome">
<Welcome />
</Route>
This Route element will allow for Welcome element to be shown only in '/welcome path'
<a href="">
, your app will send request every time user click it.import { Link } from "react-router-dom";
.
.
<li>
<Link to="/welcome">Welcome</Link>
</li>
<li>
<Link to="/products">Products</Link>
</li>
<li>
<NavLink activeClassName={classes.active} to="/welcome">
Welcome
</NavLink>
</li>
<li>
<NavLink activeClassName={classes.active} to="/products">
Products
</NavLink>
</li>
<Route path="/product-detail/:productId">
<ProductDetail />
</Route>
const params = useParams();
return (
<section>
<h1>Product Detail</h1>
<p>{params.productId}</p>
</section>
);
<Switch>
<Route path="/products" exact>
<Products />
</Route>
<Route path="/products/:productId">
<ProductDetail />
</Route>
</Switch>
<Route path="/welcome">
<Welcome />
</Route>
const Welcome = () => {
return (
<section>
<h1>The Welcome page</h1>
<Route path="/welcome/new-user">
<p>Welcome, stranger</p>
</Route>
</section>
);
};
<Route path="/" exact>
<Redirect to="/welcome" />
</Route>
const AddQuote = () => {
const history = useHistory();
const addQuotehandler = (quoteData) => {
console.log(quoteData);
history.push("/quotes");
};
return <QuoteForm onAddQuote={addQuotehandler} />;
};
<Prompt when={isEntered} message={() => "정말로 떠나시겠습니까?"} />
onFocus={formFocusHandler}
className={classes.form}
onSubmit={submitFormHandler}
>
Because the state changed to true when user click form, if user move to another route unexpectedly, Prompt message will prevent that.
const history = useHistory();
const location = useLocation();
const queryParams = new URLSearchParams(location.search);
const changeSortingHandler = () => {
history.push("/quotes?sort=" + (isSortingAscending ? "desc" : "asc"));
};
<Route path={`/quotes/${params.id}`} exact>
-after
const match = useRouteMatch();
<Route path={match.path} exact>
Switch -> Routes
There is no child component in Route
<Route path='/welcome' >
<Welcome />
</Route>
-after
<Route path='/welcome' element={<Welcome />} />
Order of routers doesn't matter anymore (algorithm improvement)
activeClassName prop removed -> must manually set
<NavLink className={(navData) => navData.isActive ? classes.active : '' }
->
If you want full redirect,
Nested route
You should wrap Nested route with '' and add star in upper Router.
You don't need repeat duplicated part of route in nested routes.
<Route path="/welcome/*" element={<Welcome />}/>
const Welcome = () => {
//some code
//nested part
<Routes>
<Route path="/new-user" element={something} />
</Routes>
//some code
}
<Link to="/products/detail"> -> <Link to="/detail">
<Route path={`${match.path}/comments`}> -> <Route path="/comments">
<Route path="/welcome/*" element={<Welcome />}/>
<Route path="/new-user" element={something} />
</Route>
import {Outlet} from 'react-router-dom'
const Welcome = () => {
//some code
//nested partsss
<Outlet />
//some code
}
const navigate = useNavigate();
navigate('/welcome') // move to path
navigate('/welcome', {replace: true}) // fully redirect
navigate(number) // move back or forward by given number