I've seen a few questions similar to this but I nothing is honestly helping me. How do you redirect with a button click in ReactJs?
Website.js
import React from 'react';
import ReactDOM from 'react-dom';
import { withRouter, useHistory } from 'react-router-dom';
//css imports
import './App.css';
import './SplashPage/splashpage.css';
//File Imports
import Resume from "./Resume/resume.js";
//Component Import
import Button from '#material-ui/core/Button';
function App() {
const history = useHistory()
return (
<div className="App">
{ <div id="cf">
<Button onClick={() => history.push(Resume)}>
CLICK ME
</Button>
</div> }
</div>
);
}
export default App;
I honestly think that I have tried too many options and I've just confused myself even more. From what I understand, the useHistory() function seems to be the correct way to go but as of now I get "TypeError: history is undefined".
Thank you for help!
SOLUTION 1: Without Routing, you can achieve it using multi-entry in webpack and by creating a separate page in your bundle using HTMLWebpackPlugin
entry: {
resume: require.resolve('./path/to/Resume.js'),,
},
output: {
filename: '[name].[contenthash:8].js'
},
plugins: [
// Generates an `index.html` file with the <script> injected.
new HtmlWebpackPlugin(
{
filename: 'resume/index.html',
inject: true,
template: 'SOME_HTML_TEMPLATE,
}
)
),
]
SOLUTION 2 With routing
It is much easier to implement
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter, Route, useHistory } from 'react-router-dom';
//css imports
import './App.css';
import './SplashPage/splashpage.css';
//File Imports
import Resume from "./Resume/resume.js";
//Component Import
import Button from '#material-ui/core/Button';
function App() {
const history = useHistory()
return (
<div className="App">
{ <div id="cf">
<Button onClick={() => history.push('resume')}>
CLICK ME
</Button>
</div> }
</div>
);
}
const Main = () => (
<BrowserRouter>
<Switch>
<Route path="/resume" component={Resume} />
<Route path="/" component={App} />
</Switch>
</BrowserRouter>
)
export default Main;
If you take a look at the documentation of useHistory you will understand the complete cycle of how this works.
Example from docs:
import { useHistory } from "react-router-dom";
function HomeButton() {
let history = useHistory();
function handleClick() {
history.push("/home"); // Here you have to pass the route where you want to redirect
}
return (
<button type="button" onClick={handleClick}>
Go home
</button>
);
}
You can study here: https://reactrouter.com/web/api/Hooks/usehistory
Updated
You were pretty close :)
Here is the solution:
import React from 'react';
import ReactDOM from 'react-dom';
import { withRouter, useHistory } from 'react-router-dom';
//css imports
import './App.css';
import './SplashPage/splashpage.css';
//Component Import
import Button from '#material-ui/core/Button';
function App() {
const history = useHistory()
return (
<div className="App">
{ <div id="cf">
<Button onClick={() => history.push('/resume')}> <-- Here changed; It will redirect to /resume
CLICK ME
</Button>
</div> }
</div>
);
}
export default App;
Index.js
import { StrictMode } from "react";
import ReactDOM from "react-dom";
import { Switch, Route, BrowserRouter as Router } from "react-router-dom";
import App from "./App";
import Resume from "./Resume";
const rootElement = document.getElementById("root");
ReactDOM.render(
<StrictMode>
<Router>
<Switch>
<Route path="/" exact component={App} />
<Route path="/resume" component={Resume} />
</Switch>
</Router>
</StrictMode>,
rootElement
);
Happy coding :)
Related
I am fairly new to using react and been following a couple of tutorials on YT, I have ran into a problem with one of them. I copied everything line by line, but my text on 'Home' and 'Login' doesnt display! I get no errors, but the page remains blank.
here is App.js
import React from 'react'
import { Routes, Route, useNavigate } from 'react-router-dom';
import Login from './components/Login';
import Home from './container/Home';
const App = () => {
return (
<Routes>
<Route path="login" element={<Login />} />
<Route path="/*" element={<Home />} />
</Routes>
);
};
export default App;
Also the index.js file:
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router } from 'react-router-dom';
import App from './App';
import './index.css';
ReactDOM.render(
<Router>
<App />
</Router>,
document.getElementById('root'),
);
**Then Login.jsx
**
import React from 'react';
const Login = () => {
return (
<div>
Login
</div>
);
};
export default Login;
Finally Home.jsx
import React from 'react';``your text``
const Home = () => {
return (
<div>
Home
</div>
);
};
export default Home;
I know I am missing something, but I cant seem to find it! Any and all help is very much appreciated!
Tried to see if I am using on old version of the BroswerROuter/Routes in React, but I have very little knowledge to see the difference just yet!
After updating to react router V6 my component no longer renders:
Trying to render the home component within my app, seems like the router is correctly organized according to React Router V6.
I am able to render the "SubredditAside" component which is located outside of the in the App.js but trying to render the Home component doesnt seem to be working
App.js:
import React from 'react';
import {
BrowserRouter,
Routes,
Route,
Router,
} from "react-router-dom";
import { selectDarkMode } from "../features/Theme/themeSlice";
import { useSelector } from "react-redux";
import './App.css';
import "../features/Theme/theme.css";
import Header from "../features/Header/Header";
import Home from "../features/Home/Home";
import SearchResults from "../features/SearchResults/SearchResults";
import SubredditsAside from "../features/SubredditsAside/SubredditAside";
import Subreddit from "../features/Subreddit/Subreddit";
import NotFoundPage from '../features/NotFoundPage/NotFoundPage';
function App() {
const darkMode = useSelector(selectDarkMode);
return (
<BrowserRouter>
<div id="app-container" className={darkMode ? "dark" : "light"}>
<Header />
<main>
<Routes>
<Route path="/" component={Home}/>
<Route path="/r/:id" component={Subreddit}/>
<Route path="/search/:id" component={SearchResults}/>
<Route component={NotFoundPage} />
</Routes>
</main>
<aside>
<SubredditsAside />
</aside>
</div>
</BrowserRouter>
);
}
export default App;
Home.js
import React, { useEffect } from "react";
import Filters from "../Filters/Filters";
import Post from "../Post/Post";
import PostLoading from "../Post/PostLoading";
import NotFoundPage from "../NotFoundPage/NotFoundPage";
import { AnimatedList } from "react-animated-list";
import { useDispatch, useSelector } from "react-redux";
import {
loadPostsHot,
selectPosts,
selectIsLoading,
selectError,
} from "../../app/appSlice";
import { setCurrentSubreddit } from "../SubredditsAside/SubredditAsideSlice"
import { setCurrentFilter } from "../Filters/filtersSlice";
const Home = ({ match }) => {
const dispatch = useDispatch();
const posts = useSelector(selectPosts);
const isLoading = useSelector(selectIsLoading);
const error = useSelector(selectError);
const currentSubreddit = match.params.id;
useEffect(() => {
dispatch(setCurrentFilter("hot"));
dispatch(setCurrentSubreddit(""));
dispatch(loadPostsHot());
}, [dispatch, currentSubreddit]);
if (error) {
return <NotFoundPage />;
}
return (
<>
<Filters />
{isLoading ? (
<AnimatedList>
<PostLoading />
<PostLoading />
<PostLoading />
</AnimatedList>
) : (
posts.map((post, index) => (
<Post key={index} post={post} postIndex={index} />
))
)}
</>
);
};
export default Home;
Index.js:
import React from 'react';
import { ReactDOM } from 'react';
import { createRoot } from 'react-dom/client';
import { Provider } from 'react-redux';
import { store } from './app/store';
import App from '../src/app/App';
import reportWebVitals from './reportWebVitals';
import './index.css';
import "#fontsource/roboto";
// import "./base.css";
import { BrowserRouter } from 'react-router-dom';
const container = document.getElementById('root');
const root = createRoot(container);
root.render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>
);
I want to have a simple button that when clicked redirects a user to a route defined in my Index.tsx file.
When the button is clicked, the url bar is correctly changed to "/dashboard", however my component (just an h1) does not appear. If I reload chrome at that point it will appear.
Here's my code (Index.tsx):
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import { Route, Switch } from "react-router-dom";
import { Router } from "react-router";
import { createBrowserHistory } from "history";
import Dashboard from "./components/Dashboard";
const appHistory = createBrowserHistory();
ReactDOM.render(
<React.StrictMode>
<Router history={appHistory}>
<Switch>
<Route exact path="/" component={App} />
<Route path="/dashboard" component={Dashboard} />
</Switch>
</Router>
</React.StrictMode>,
document.getElementById("root")
);
Here's my start of a Login form (the first route above, App, renders it).
(Login.tsx):
import React, { useState } from "react";
import {Button} from "#material-ui/core";
import { useHistory} from "react-router-dom";
export const Login: React.FC = (props) => {
const classes = useStyles();
let history = useHistory();
const [email, setEmail] = useState<string>("");
const [password, setPassword] = useState<string>("");
const validateForm = (): boolean => {
return true;
};
const handleLoginClick = (
event: React.MouseEvent<HTMLButtonElement, MouseEvent>
) => {
history.push("/dashboard");
};
return (
<form>
<div>
<Button
onClick={handleLoginClick}
color="inherit"
type="button"
>
Login
</Button>
</div>
</form>
);
};
export default Login;
Replace this line
import { Router } from "react-router"
with
import {BrowserRouter as Router } from "react-router-dom";
Try importing the Router from react-router-dom - the rest seems correct
import { Route, Router, Switch } from "react-router-dom";
react-router is mostly for internal usage - you only interact with react-router-dom
I can refresh my pages, but when I use the back and forward buttons in chrome my app breaks.
I get this error: Uncaught TypeError: this.props.cars.map is not a function. I'm very new to React Router and I feel like this should be an easy fix.
This is my App component:
import React, { Component } from "react";
import { BrowserRouter, Route, Switch } from "react-router-dom";
import CarsIndex from "../containers/cars_index";
import CarNew from "../containers/car_new";
import CarShow from "../containers/car_show";
import Error from "./error";
function App() {
return (
<Switch>
<Route path="/" component={CarsIndex} exact />
<Route path="/new" component={CarNew} />
<Route path="/show/:id" component={CarShow} />
<Route component={Error} />
</Switch>
);
}
export default App;
and this is my index.jsx:
import React, { Component } from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import { createStore, combineReducers, applyMiddleware } from "redux";
import reduxPromise from "redux-promise";
import logger from "redux-logger";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import { createBrowserHistory } from "history";
import "../assets/stylesheets/application.scss";
import App from "./components/app";
import carsReducer from "./reducers/cars_reducer.jsx";
const initialState = {
garage: "lenny",
cars: [],
};
const reducers = combineReducers({
garage: (state = null, action) => state,
cars: carsReducer,
});
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const middleWares = composeEnhancers(applyMiddleware(logger, reduxPromise));
// render an instance of the component in the DOM
ReactDOM.render(
<Provider store={createStore(reducers, initialState, middleWares)}>
<Router>
<App />
</Router>
</Provider>,
document.getElementById("root")
);
Thanks in advance.
This from react router page
v5
import { useHistory } from "react-router-dom";
function App() {
const { go, goBack, goForward } = useHistory();
return (
<>
<button onClick={() => go(-2)}>
Go 2 pages back
</button>
<button onClick={goBack}>Go back</button>
<button onClick={goForward}>Go forward</button>
<button onClick={() => go(2)}>
Go 2 pages forward
</button>
</>
);
}
v6
import { useNavigate } from "react-router-dom";
function App() {
const navigate = useNavigate();
return (
<>
<button onClick={() => navigate(-2)}>
Go 2 pages back
</button>
<button onClick={() => navigate(-1)}>Go back</button>
<button onClick={() => navigate(1)}>
Go forward
</button>
<button onClick={() => navigate(2)}>
Go 2 pages forward
</button>
</>
);
}
I think 'this.props.cars.map' is not a function mean that car is not an array so map function not call on it.
My advice (but probably out of date) if you 'very new to React Router' not start with redux example.
I have this code, and it is very good working on other environment without webpack.
This is main.js on frontend
import ReactDOM from "react-dom";
import React from "react";
//import { Router, Route, hashHistory } from 'react-router';
import { BrowserRouter, Route } from "react-router-dom";
import App from "./components/App.jsx";
import WizardIndex from "./components/index.js";
ReactDOM.render(
<BrowserRouter>
<App>
<Route path="/signup" component={WizardIndex} />
</App>
</BrowserRouter>,
document.getElementById("mount-point")
);
This is App.jsx
import React from "react";
import { Link } from "react-router-dom";
class App extends React.Component {
render() {
const { children } = this.props;
return (
<div className="App">
<div className="menu-bar">
<div className="menu-item">
<h3>App</h3>
<Link to="/signup">Signup</Link>
</div>
<div className="content">{children}</div>
</div>
</div>
);
}
}
export default App;
And Here I include WizardIndex file index.js
import React from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import { Values } from "redux-form-website-template";
import store from "./store";
import showResults from "./showResults";
import WizardForm from "./WizardForm";
class WizardIndex extends React.Component {
render() {
return (
<h1>
Hello!!!React Router
</h1>
);
}
}
export default WizardIndex;
I see Signup link - button on the localhost:8050 But, Why
Why I can not see nothing after I press Signup button
I didnt have any error No in console webpack (there is all green ) Not in console of browser And when I reload the page localhost:8050/signup I get this note in browser but not in consol Cannot GET /signup