Creating a button to a new route reactJS - javascript

Really struggling with understanding how to create a button which routes to a new page (search.js).
I've tried different methods which some have worked in routing to the link but the page does not change (but I can see the url being changed to the search page).
*sorry at this point the code has been butchered with numerous attempts of adding the button
App.js -
```
import React, { useState } from "react";
import { BrowserRouter as Router, Link } from 'react-router-dom';
import Route from 'react-router-dom/Route';
function App() {
const [joke, setJoke] = useState()
const newJoke = () => {
fetch("http://api.icndb.com/jokes/random")
.then(result => result.json())
.then(result2 => {
console.log(result2)
setJoke(result2.value.joke)
})
return newJoke
}
return (
<Router>
<div className="jokeSection">
<h1>Chuck norris jokes</h1>
<h3>{joke}</h3>
<button onClick={() => newJoke()}>Click here for a chuckle</button>
<button onClick={() => { this.props.history.push("/search"); }}>Search!!</button>
</div>
<ul>
<li>
<Link to="/App">Home</Link>
</li>
<li>
<Link to="/search">Search</Link>
</li>
</ul>
</Router>
)
}
export default App;```
Search.js
import React from "react";
function Search() {
return (
<div>
<h2>Search</h2>
</div>
);
}
export default Search;
Ideally I want a button (just like the button onClick) to route to a new page - search.js.
I'm new to ReactJS and have tried to watch many tutorials but i'm having difficulty.

In your app.js file you need to have <Route> as children of <Router> not <Link>.
You can look over this code:
<Router>
<div>
<Route exact path="/">
<Home />
</Route>
<Route path="/news">
<NewsFeed />
</Route>
</div>
</Router>
The above code will create routes for your react application. Then you can navigate to each of them using <Link> in your Navbar rather than ordinary a tag.

Related

HTML not showing up on React webpage [duplicate]

This question already has an answer here:
react-router-dom v6 Routes showing blank page
(1 answer)
Closed 18 hours ago.
So as the title suggests, Im looking for a reason as to why my webpage is not showing up on the website
Here is the App.js file
import { useState, useEffect } from "react";
import { BrowserRouter as Router, Routes, Route, Link } from "react-router-dom";
import axios from "axios";
import Post from "./Post.js";
function App() {
const [posts, setPosts] = useState([]);
useEffect(() => {
axios.get("https://jsonplaceholder.typicode.com/posts").then((response) => {
setPosts(response.data);
});
}, []);
return (
<Router>
<div>
<nav>
<ul>
<li>
<Link to="/">All Posts</Link>
</li>
</ul>
</nav>
<Routes>
<Route path="/" exact>
<h1>All Posts</h1>
<ul>
{posts.map((post) => (
<li key={post.id}>
<Link to={`/posts/${post.id}`}>{post.title}</Link>
</li>
))}
</ul>
</Route>
<Route path="/posts/:id">
<Post />
</Route>
</Routes>
</div>
</Router>
);
}
export default App;
I made Post.js a separate js file from App like this:
import { useState, useEffect } from "react";
import axios from "axios";
function Post() {
const [post, setPost] = useState(null);
const id = window.location.pathname.split("/")[2];
useEffect(() => {
axios.get(`https://jsonplaceholder.typicode.com/posts/${id}`).then((response) => {
setPost(response.data);
});
}, [id]);
if (!post) {
return <div>Loading...</div>;
}
return (
<div>
<h1>{post.title}</h1>
<p>{post.body}</p>
</div>
);
}
export default Post;
The site is running as well. I can access everything that is there, but for some reason, it is just a blank page.
I hope you can help me with this issue. Thank you
You cannot directly put the content to be rendered under <Route>. Instead, set the element attribute on the <Route>.
For example:
<Route path="/posts/:id" element={<Post/>}/>
You also need to extract the content for all posts into a separate component.
<Route path="/" element={<AllPosts/>}>

Rendering child components without the parent component in React Router

I have simple react app that lists different shops from a mongodb database for example (HM, Amazon, Lindex etc) and displayed as cards with links (As seen in Boutique.js)
Desired solution:
I want so that each pressed card leads to a new page using router.
For example: If i press the card that is named "HM" then I want to be directed to /boutiques/HM that runs the Template component (as shown in Boutique.js) without parent component being rendered (except for the navbar)
The next card that is named "Amazon" should direct me to /boutiques/Amazon
The next card etc etc
Current solution:
My current solution renders the Template component under the cards whenever you click any of the cards. The cards are still visible in the page. I want so that the Template component renders without the parent showing (the cards). It should be just the navbar and a blank whitepage
Question:
How do I restructure my current solution to reach my desired solution?
App.js
import { BrowserRouter, Link, Route, Routes } from "react-router-dom";
import React from "react";
import "./CouponDeals.css";
import Boutiques from "./Boutiques";
import Home from './Home';
function App() {
return (
<BrowserRouter>
<div className="main-container">
<div className="navbar-section-container">
<div class="navbar">
<Link to="/">Hem</Link>
<Link to="/boutiques">Butiker</Link>
</div>
</div>
<Routes>
<Route exact path="/" element={<Home />} />
<Route path="/boutiques/*" element={<Boutiques />} />
</Routes>
</div>
</BrowserRouter>
);
}
export default App;
Boutiques.js
import React, { useEffect, useState } from "react";
import {Link, Route, Routes } from "react-router-dom";
import axios from "./Axios";
import Template from "./Template.js";
const Boutiques = () => {
const [deals, setDeals] = useState([]);
useEffect(() => {
async function fetchData() {
const req = await axios.get("/butiker");
setDeals(req.data);
}
fetchData();
}, []);
return (
<React.Fragment>
<div className="header-section">
<h1 className="title">All Boutiques</h1>
</div>
<div className="card-section-container">
<div className="deals-container">
{deals.length > 0 ? (
deals.map((deal, index) => (
<div key={index} className="deal">
<div className="button-container">
<Link to={`${deal.name}`} className="butiker-button">
<img src={deal.imgUrl} alt={deal.name} />
</Link>
</div>
</div>
))
) : (
<p className="no-results">No results found</p>
)}
</div>
</div>
<Routes>
{deals.map((deal, index) => (
<Route
key={index}
path={`${deal.name}`}
element={<Template name={deal.name} />}
/>
))}
</Routes>
</React.Fragment>
);
};
export default Boutiques;
The selected boutique is showing below the cards because you implemented a router in the bottom Boutiques.js. Instead of using this approach you should try to add another dynamic Route in App.js that uses the name of the boutique as a parameter.
App.js
<Routes>
<Route exact path="/" element={<Home />} />
<Route path="/boutiques/" element={<Boutiques />} />
<Route path="/boutiques/:name" element={<Template />} />
</Routes>
You will probably have to refactor your Template component so it retrieves the id of the boutique from the URL. You can do this like so:
let { name } = useParams();

React => Make action on back button on Android Google Chrome (Not React Native)

I have a case where there is the application written in React (not React Native).
The application runs on the web. So for example I use Google Chrome on my mobile (android).
I'm on some URL in my app. Is it possible to add some action when the user clicks the 'back icon'? To move to the previous page for example?
I know that we can easily achieve it on React Native, but in just React?
I mean this back icon:
Is it possible?
Thanks
You can use React Router there is a hook called useHistory you can use it go back in React
import React from "react";
import {
BrowserRouter as Router,
Switch,
Route,
Link,
useHistory
} from "react-router-dom";
const Foo = () => {
const history = useHistory();
return (
<div>
<button onClick={history.goBack}>Back</button>
<p>foo</p>
</div>
);
};
const Bar = () => {
const history = useHistory();
return (
<div>
<button onClick={history.goBack}>Back</button>
<p>bar</p>
</div>
);
};
export default function App() {
return (
<Router>
<div>
<ul>
<li>
<Link to="/foo">foo</Link>
</li>
<li>
<Link to="/bar">bar</Link>
</li>
</ul>
<Switch>
<Route path="/foo" children={<Foo />} />
<Route path="/bar" children={<Bar />} />
</Switch>
</div>
</Router>
);
}
for more details on this you follow this docs page

React Router double slash after rendering the Link component

I just created a react app using create-react-app and this is my code:
import React, { Component } from "react";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
// import Navigation from "./components/navigation";
const Home = () => <div><h1>Home</h1></div>;
const Profile = () => <div><h1>Profile</h1></div>;
const Auth = () => <div><h1>Login</h1></div>;
const Navigation = () => (
<div>
<Link to="/">Home</Link>
<Link to="/auth">Login</Link>
<Link to="/profile">Profile</Link>
</div>
);
class App extends Component {
render() {
return (
<Router>
<div>
<Navigation />
<div>
<Route exact path="/" component={Home} />
<Route path="/auth" component={Auth} />
<Route path="/profile" component={Profile} />
</div>
</div>
</Router>
);
}
}
export default App;
But it renders the a tag get doubles slash and every time that I click on any link it put another slash on the URL.
[Updated]Here how its look like after I clicked a few times:
But if I instead clicking in the link type the exactly the right URL it works. How can I fix this? And why this is happing cause I just copy it from the documentation.

Mimic Wordpress Permalink Structure in a React Application

I'm using React to build the front-end of a site that uses Wordpress as a back-end. My goal is to mimic the most simple permalink structure in Worpdress, that is the site domain + the slug of the page or posts, without the addition of any /posts/ or /news/ or whatever. In other words, something like http://example.com/hello-world/for posts and http://example.com/about/ for pages.
I'm very new to React and I'm having some trouble understanding how to do that with React Router.
Here's what I have so far:
import React from 'react';
import { Switch, Route } from 'react-router-dom';
import HomePage from './pages/HomePage';
import MainHeader from './components/main-header/MainHeader';
import SinglePost from './pages/SinglePost';
const Layout = () => {
return (
<div>
<MainHeader />
<Switch>
<Route exact path="/" component={ HomePage } />
<Route exact path="/:slug" render={ props => <SinglePost { ...props } /> } />
<Route render={ () => { return( <p>Not Found</p> ) } } />
</Switch>
</div>
);
}
export default Layout;
This works fine for loading single posts with the permalink structure I've mentioned above, e.g. http://example.com/hello-world. The problem is, when I try to reach a page such as http://example.com/about, path="/:slug"is also matched, which means that the SinglePost component will be used for pages as well, while I want to use a different one.
How can I use different components for single posts and pages, while keeping the same permalink structure?
By the way, below is how I render my list of posts, with links to each individual post. Should I perhaps edit Link in some way?
import React from 'react';
import { Route, Link } from 'react-router-dom';
const ListPosts = ( props ) => {
let postsList = props.posts.map( ( post, index ) => {
return(
<article key={ index }>
<h2><Link to={ post.slug }>{ post.title.rendered }</Link></h2>
</article>
)
});
return (
<section className="posts">
<h1>Posts</h1>
{ postsList }
</section>
);
}
export default ListPosts;

Categories

Resources