How to load the child component under the parent component - reactjs

In react I am using tsx file. where how to load the child component under the parent component?
here is my products page:
import React from "react";
import {
Link,
Route,
Switch,
useRouteMatch,
useParams
} from "react-router-dom";
import "./products.scss";
const Shoes = React.lazy(() => import("./shoes/shoes.component"));
const Cloths = React.lazy(() => import("./cloths/cloths.component"));
export default class Products extends React.Component {
render() {
return (
<>
<header>
<Link to="/shoe">Shoes</Link>
<Link to="/cloths">Cloths</Link>
</header>
<h1>Products page</h1>;
<main>
<h2>Subpage goes here </h2>
<p>sub pages should load here </p>
</main>
</>
);
}
}
on click of the child Link, i looking to load them in to main element.
Live Demo

Please check docs for more information
<div>
<header>
<Link to="/products/shoe">Shoes</Link>
<Link to="/products/cloths">Cloths</Link>
</header>
<h1>Products page</h1>
<Route path={`/products/shoe`}>
<Shoes />
</Route>
<Route path={`/products/cloths`}>
<Cloths />
</Route>
</div>
demo

Related

Create a Default page without sidebar and route

Goal:
Show the first page (default page) that contain a button that goes to the page with sidebar link Home and About using Router.
Problem:
Today, you have a menu with link Home and About but if I want a default page (that is the main page that you enter) and then you go to another page that has sidebar and using route.
How should it be created?
Info:
*Newbie in Reactjs
*The main page (default) should not contain any sidebar or any route.
Stackblitz:
https://stackblitz.com/edit/react-k19hye?
import React from 'react';
import './style.css';
import React, { Component } from 'react';
import { render } from 'react-dom';
import { BrowserRouter as Router, Route, Link } from 'react-router-dom';
const Nav = () => (
<div>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
</ul>
</div>
);
const HomePage = () => <h1>Home Page</h1>;
const AboutPage = () => <h1>About Page</h1>;
export default class App extends Component {
constructor() {
super();
this.state = {
name: 'React',
};
}
render() {
return (
<Router>
{/* Router component can have only 1 child. We'll use a simple
div element for this example. */}
<div>
<Nav />
<Route exact path="/" component={HomePage} />
<Route path="/about" component={AboutPage} />
</div>
</Router>
);
}
}
render(<App />, document.getElementById('root'));
In order to set another default page, you should first update the route to HomePage to /home. And then define another route for the DefaultPage like <Route exact path="/" component={DefaultPage} />. In order to hide sidebar on the DefaultPage, you can use Switch to show only DefaultPage on route /.
You can take a look at this updated stackblitz forked from your original example for a live working example. Here is the final full code of this usage:
import React from 'react';
import './style.css';
import React, { Component } from 'react';
import { render } from 'react-dom';
import {
BrowserRouter as Router,
Route,
Link,
Switch,
useHistory,
} from 'react-router-dom';
const Nav = () => (
<div>
<ul>
<li>
<Link to="/home">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
</ul>
</div>
);
const DefaultPage = () => {
const history = useHistory();
return (
<div>
<h1>Default Page</h1>
<button onClick={() => history.push('/main')}>go to main</button>
</div>
);
};
const HomePage = () => <h1>Home Page</h1>;
const AboutPage = () => <h1>About Page</h1>;
export default class App extends Component {
constructor() {
super();
this.state = {
name: 'React',
};
}
render() {
return (
<Router>
<Switch>
{/* Router component can have only 1 child. We'll use a simple
div element for this example. */}
<Route exact path="/" component={DefaultPage} />
<div>
<Nav />
<Route exact path="/home" component={HomePage} />
<Route exact path="/about" component={AboutPage} />
</div>
</Switch>
</Router>
);
}
}
render(<App />, document.getElementById('root'));

React-router URL changes but page is still unchanged

I am new to react and react-router, so please go easy on me.
I am trying to implement router in my Todo List project, where path="/" takes me to my todo list and path="/id" takes me to a test page (later will show the description of the task).
When I click the link that takes me to "/id", the URL in the browser changes but the page/content doesn't. However, when I refresh my browser, the test page loads.
I have put the Switch in App.js shown below.
import React, { Component } from "react";
import "./App.css";
import TodoList from "./components/TodoList";
import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";
import Test from "./components/Test";
class App extends Component {
render() {
return (
<Router>
<div className="todo-app">
<p>
<Link to="/">Home</Link>
</p>
<Switch>
<Route exact path="/" component={TodoList} />
<Route path={`/id`} component={Test} />
</Switch>
</div>
</Router>
);
}
}
export default App;
And I have put the Link to "/id" as shown below in a child component of component which is called here in App.js.
<div key={todo.id}>
<Link className="todo-text" to={`/id/${todo.id}`}>
{todo.text}
</Link>
</div>
Am I missing something which is causing my component to not load when I click the link?
Edit: Here's a link to my project. https://stackblitz.com/edit/react-7cpjp9?file=src/index.js
Issue
Ok, the issue is exactly as I had suspected. You are rendering multiple routers in your app. The first is a BrowserRouter in your index.js file, the second, another BrowserRouter in App.js, and at least a third BrowserRouter in Todo.js. You need only one router to provide a routing context for the entire app.
The issue here is that the router in Todo component is the closest router context to the links to specific todo details. When a link in Todo is clicked, this closest router handles the navigation request and updates the URL in the address bar. The blocks, or "masks", the router in App component or index.js that is rendering the routes from "seeing" that a navigation action occurred. In other words, the URL in the address bar is updated by the inner router, but the outer router doesn't know to render a different route.
Solution
Keep the BrowserRouter wrapping App in index.js and remove all other routers used in your app.
App - Remove the Router component. Also, reorder the routes/paths from most specific to least specific so you don't need to specify the exact prop on every route. Allows more specific paths to be matched and rendered before less specific paths by the Switch component.
class App extends Component {
render() {
return (
<div className="todo-app">
<p>
<Link to="/">Home</Link>
</p>
<Switch>
<Route path="/id/:todoId" component={Test} />
<Route path="/" component={TodoList} />
</Switch>
</div>
);
}
}
Todo - Remove the Router component. Move the key={todo.id} up to the outer-most element so when todos array is updated React can reconcile updates.
class Todo extends Component {
constructor(props) {
super(props);
this.state = {
id: null,
value: "",
details: "",
};
this.submitUpdate = this.submitUpdate.bind(this);
}
submitUpdate(value) {
const { updateTodo } = this.props;
updateTodo(this.state.id, value);
this.setState({
id: null,
value: "",
});
}
render() {
const { todos, completeTodo, removeTodo } = this.props;
if (this.state.id) {
return <TodoForm edit={this.state} onSubmit={this.submitUpdate} />;
}
return todos.map((todo, index) => (
<div
className={todo.isComplete ? "todo-row complete" : "todo-row"}
key={todo.id}
>
<div>
<Link className="todo-text" to={`/id/${todo.id}`}>
{todo.text}
</Link>
</div>
<div className="icons">
<RiCloseCircleLine
onClick={() => removeTodo(todo.id)}
className="delete-icon"
/>
<TiEdit
onClick={() => this.setState({ id: todo.id, value: todo.text })}
className="edit-icon"
/>
<RiCheckboxCircleLine
onClick={() => completeTodo(todo.id)}
className="delete-icon"
/>
</div>
</div>
));
}
}
First of all the approach, you are taking for dynamic routing is wrong.
It should be like this you will have to add the exact keyword on the dynamic route.
<Route exact path="/id/:todoId" component={Test} />
And
<div key={todo.id}>
<Link className="todo-text" to={`/id/${todo.id}`}>
{todo.text}
</Link>
import React, { Component } from "react";
import "./App.css";
import TodoList from "./components/TodoList";
import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";
import Test from "./components/Test";
class App extends Component {
render() {
return (
<Router>
<div className="todo-app">
<p>
<Link to="/">Home</Link>
</p>
<Switch>
<Route exact path="/" component={TodoList} />
**<Route exact path={`/id`} component={Test} />**
</Switch>
</div>
</Router>
);
}
}
export default App;

Chrome is showing strange errors for my React App after installing Router

I'm working on converting a website from a static HTML/CSS/JS site into a React SPA and I want to use React Router for navigation. I installed Router into the correct directory, ran npm start from the correct directory, and my Terminal shows that everything compiled successfully, but my browser looks like this:
App.js file:
import React from 'react';
import './styles/App.css';
import Navbar from './components/Navbar';
class App extends React.Component {
render() {
return (
<div className = "App">
<div id ='container' className = 'container light'>
<Navbar />
</div>
</div>
)
}
}
export default App;
Navbar.js file:
import React, { Component } from 'react';
import '../styles/App.css';
import logo from '../img/logo.png'
import {
BrowserRouter as Router,
Switch,
Route,
Link
} from "react-router-dom";
import App from '../App';
import About from './About';
import Portfolio from './Portfolio';
class Navbar extends Component {
render() {
return (
<Router>
<div className="Navbar">
<nav>
<ul className="navlist">
<Link to={App}>
<li className="active">Home</li>
</Link>
<Link to={About}>
<li>About Me</li>
</Link>
<Link to={App}>
<img className="brand" src={logo} alt="" />
</Link>
<Link to={Portfolio}>
<li>Portfolio</li>
</Link>
<li className="toggler"><span role="img" aria-label="dark moon">🌑</span></li>
</ul>
</nav>
<Switch>
<Route path= {About}>
<About />
</Route>
<Route path= {Portfolio}>
<Portfolio />
</Route>
<Route path= '{App}'>
<App />
</Route>
</Switch>
</div>
</Router>
)
}
}
export default Navbar;
About.JS
import React, { Component } from 'react';
import '../styles/App.css';
import Navbar from './Navbar'
class About extends Component {
render() {
return (
<div className="About">
<Navbar />
<h1>Hello World, This is the About Page</h1>
</div>
)
}
}
export default About;
Portfolio.JS
import React, { Component } from 'react';
import '../styles/App.css';
import Navbar from './Navbar'
class Portfolio extends Component {
render() {
return (
<div className="Portfolio">
<Navbar />
<h1>Hello World, This is the Portfolio Page</h1>
</div>
)
}
}
export default Portfolio;
I'm new to React and I'm not sure what I've done wrong. Happy to share any additional information needed.
That's not how Link is used, the to prop should have the path you want to navigate, and then you have to use the Route HOC with two options, pass the component as a child or in the component prop
Link
<Link to="/about">
About
</Link>
Route
<Route path="/about" component={About} />
<Route path="/about">
<About/>
</Route>

Hiding some navigation bar links in some of the react components: React+ React-Router+Typescript

I am a bit new to React.
I have a situation where I need to hide some navigation bar links in some components where as in the rest, I want to display them.
Actually been using react router V4 and typescript.
Need to hide page1 and page2 links when it comes to signup and login pages.
Say I also have a getstarted page that loads when the application is launched , here also I would like to hide the links.
Show the links in rest of the components.
Help would be appreciated
Router Code
import * as React from 'react';
import NavBar from './NavBar';
import SignUp from './SignUp';
import Page1 from './Page1';
import Page2 from './Page2';
import Login from './Login';
import GetStarted from './GetStarted';
import { BrowserRouter as Router , Switch , Route} from 'react-router-dom';
const NotFound = () => (
<div><h1>404.. This page is not found!</h1></div>
);
export default class App extends React.Component<{}, {}> {
render() {
return(
<Router>
<div className='container'>
<NavBar/>
<div className='body'>
<Switch>
<Route exact={true} path='/' component={GetStarted}/>
<Route path='/getstarted' component={GetStarted}/>
<Route path='/signup' component={SignUp}/>
<Route path='/login' component={Login}/>
<Route path='/page1' component={Page1}/>
<Route path='/page2' component={Page2}/>
<Route component={NotFound} />
</Switch>
</div>
</div>
</Router>
)
}
}
Navigation Bar Component
import React from 'react';
import { Link } from 'react-router-dom';
export default class NavBar extends React.Component<{}, {}> {
render() {
return (
<nav className="nav">
/*some logo will be displayed here followed by the links*/
<div className="container">
<ul className="item-wrapper">
<li>
<Link to="/page1">Link 1</Link>
</li>
<li>
<Link to="/page2">Link 2</Link>
</li>
</ul>
</div>
</nav>
);
}
}
Since you provide a login function, surely somewhere in your state you store the information whether a user is logged in or not. Use this state to determine whether to display the links:
import React from 'react';
import { Link } from 'react-router-dom';
export default class NavBar extends React.Component<{}, {}> {
render() {
return (
<nav className="nav">
<div className="container">
{user.loggedIn /* boolean indicating whether user is logged in */ &&
<ul className="item-wrapper">
<li>
<Link to="/page1">Link 1</Link>
</li>
<li>
<Link to="/page2">Link 2</Link>
</li>
</ul>
}
</div>
</nav>
);
}
}

Routing in React JS on click

I am new to React and I want to navigate to another component on button click. I just want to perform a simple routing. This is the code that I tried. But I am not able to route it.
import React, { Component } from 'react';
import { BrowserRouter as Router, Route, Switch, Redirect } from 'react-router-dom'
import Hello from './HelloComponent';
class App extends Component {
constructor(props) {
super(props);
this.try = this.try.bind(this)
}
try = () => {
alert();
<div>
<Router>
<Route path="/hello" component={Hello} />
</Router>
</div>
}
render() {
return (
<div className="App">
<div className="container">
<button id="b1" onClick={this.try}>Click me</button>
</div>
</div>
);
}
}
export default App;
Please help me with this code to perform basic routing in react JS
You cannot return JSX to onClick handler since it won't do anything with it.
You need to configure your Routes in render in advance and use history.push to change the Route
Below is a sample code that you can refer
import React, { Component } from 'react';
import { BrowserRouter as Router, Route,Switch, Redirect} from 'react-router-dom'
import Hello from './HelloComponent';
class App extends Component {
try = () => {
this.props.history.push('/hello');
}
render() {
return (
<div className="App">
<div className="container">
<button id="b1" onClick ={this.try}>Click me</button>
<Route path="/hello" component={Hello}/>
</div>
</div>
);
}
}
export default () => (
<div>
<Router>
<Route component={App} />
</Router>
</div>
);
I recommend you look at the doc.
<Route path="/hello" component={Hello}/> will display the component Hello exactly where the <Route/> is, but I think your function will do nothing here as it returns a <div> but where does it go?
You need some sort of "higher" component that will render your routes, then call a <Link/>
Then try nesting the button inside the <Link/> ?
<Link to="/??">
<button id="b1">
Click me
</button>
</Link>
in your code
try = () => {
alert();
<div>
<Router>
<Route path="/hello" component={Hello}/>
</Router>
</div>
}
your just pushing the route and it's not a action to take you to different page
bellow code will work fine and it's good practice to place router in separate component. click here you can find this code in codesandbox
import React, { Component } from "react";
import ReactDOM from "react-dom";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import "./styles.css";
function RouterComponet() {
return (
<Router>
<Switch>
<Route exact path="/" component={App} />
<Route path="/user" component={User} />
</Switch>
</Router>
);
}
class App extends Component {
constructor(props) {
super(props);
}
onClick = () => {
this.props.history.push("/user");
};
render() {
return (
<div>
<h1>App component</h1>
<a onClick={this.onClick} className="link">
click here
</a>{" "}
to user page
</div>
);
}
}
class User extends Component {
constructor(props) {
super(props);
}
onClick = () => {
this.props.history.push("/");
};
render() {
return (
<div>
<h1>User Componet</h1>
<a onClick={this.onClick} className="link">
click here
</a>{" "}
to back
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<RouterComponet />, rootElement);
I have created a demo that brings it all together. It has three files App.js, About.js, Contacts.js. To Navigate to any component, you need to add its route in App.js, Then depending on the location of your button (About.js), wrap it with Link that helps the element navigate to the specified route. When clicked, the Contacts component should be loaded. Hope this helps. code demo
App.js
import React from "react";
import { Switch, Route, BrowserRouter } from "react-router-dom";
import About from "./About";
import Contact from "./Contacts";
function App() {
return (
<BrowserRouter>
<Switch>
<Route path="/" component={About} exact />
<Route path="/contacts" component={Contact} />
</Switch>
</BrowserRouter>
);
}
export default App;
About.js
import React from "react";
import { Link } from "react-router-dom";
function About() {
return (
<div>
<p>
Lorem Ipsum is simply dummy text of the printing and typesetting
industry.
</p>
<Link to="/contacts">
<button>click me</button>
</Link>
</div>
);
}
export default About;
Contacts.js
import React from "react";
function Contact() {
return <div>Call me!!</div>;
}
export default Contact;
This is the first SO post on google, so I'd like answer the question with updated coding style and answer:
From react v6 you use the useNavigation hook. (Reference)
import { useNavigate } from 'react-router-dom';
export const MyComponent = () => {
const navigate = useNavigate();
return (
<>
<button
onClick={() => {
navigate('/');
}}
>
click me
</button>
</>
);
};

Resources