Sukma Saputra
Sukma Saputra

Reputation: 1599

react js How to open new page from child link on content without show previous page

I'm new use reactjs and now I learning to make web apps using react js. But now I am deadlocked on this issue.

I want to show new content such as opening a new page when clicking a link in the content without show previous content.

Here's my code:

App.js

import React, { Component } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';

import Header from './components/Header';
import Footer from './components/Footer';
import Siswa from './components/Siswa';

class App extends Component {
    
    render() {
        
        return (
            <Router>
                <div>
                    <Header />
                    
                    <Switch>
                        <Route exact path="/" component={Home} />
                        <Route path="/siswa" component={Siswa} />
                    </Switch>
                    
                    <Footer />
                </div>
            </Router>
        );
    }
}

const Home = () => (
    <div style={{ fontSize:'13px' }}>
    <h3>Home</h3>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
    </div>
);

export default App;

Siswa.js

import React from 'react';
import { BrowserRouter as Router, Route, Link } from 'react-router-dom';
import DetailSiswa from './DetailSiswa';

const SISWAS = [
    {id: 0, username: "luke", nama_lengkap: "Luke Skywalker", tempat_lahir: "Tangerang"},
    {id: 1, username: "solo", nama_lengkap: "Han Solo", tempat_lahir: "Bandung"},
    {id: 2, username: "queen", nama_lengkap: "Queen Apailana", tempat_lahir: "Bandung Barat"}
]; 

const Siswa = ({ match }) => {
    return (
        <div>
            <ul>
            { SISWAS.map( i => 
                <li key={i.id}>
                    <Link key={i.id} to={`${match.url}/${i.username}`}>{i.nama_lengkap}</Link>
                </li>
            )}
            </ul>

            <Route path={`${match.url}/:username`} component={DetailSiswa} />
        </div>
    );
}

export default Siswa;

DetailSiswa.js

import React from 'react';

const DetailSiswa = ({ match }) => {
    return (
        <div>
            <h2>Data Siswa</h2>
            <h3>{match.params.username}</h3>
        </div>
    );
}

export default DetailSiswa;

This is what I need. enter image description here

Upvotes: 1

Views: 2239

Answers (2)

Weder Ribas
Weder Ribas

Reputation: 359

You are using nested routes, that will always render the components from the previous route that rendered the component Siswa. You could learn more about this in this section of the official documentation for React Router.

In order to have the desired effect (rendering only the DetailSiswa when reaching the route /siswa/:username), move the route from Siswa.js to the App.js component:

import ReactDOM from "react-dom";

import React, { Component } from "react";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";

import Siswa from "./Siswa";
import DetailSiswa from "./DetailSiswa";

class App extends Component {
render() {
    return (
    <Router>
        <div>
        <Switch>
            <Route exact path="/" component={Home} />
            <Route exact path="/siswa" component={Siswa} />
            <Route path={`/siswa/:username`} component={DetailSiswa} />
        </Switch>
        </div>
    </Router>
    );
}
}

const Home = () => (
<div style={{ fontSize: "13px" }}>
    <h3>Home</h3>
    <p>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
    tempor incididunt ut labore et dolore magna aliqua.
    </p>
</div>
);

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Noticed that it is required to move the DetailSiswa import to the App component, so you can render the component within the route.

See the complete solution in this CodeSandbox.

Upvotes: 1

Jacob
Jacob

Reputation: 78920

Even though your /siswa and /siswa/:username share a common URL segment, if the content they render is mutually exclusive, it's probably easiest to just move the detail route top-level:

<Switch>
  <Route exact path="/" component={Home} />
  <Route exact path="/siswa" component={Siswa} />
  <Route exact path="/siswa/:username" component={SiswaDetail} />
</Switch>

Upvotes: 1

Related Questions