Search by

    Terakhir diperbaharui: Oct 24, 2020

    Membuat Front End #2

    4. Membuat Navigasi Component

    Kita akan menyelesaikan masalah yang ada pada bagian sebelumnya yaitu:

    1. Semua page ditampilkan dalam satu page, diakses dengan satu alamat
    2. Duplicate code
    3. Tampilan tidak rapi

    Untuk permasalahan pertama kita harus menambahkan navigation agar setiap page dapat diakses dengan alamatnya masing-masing.

    React Router

    Kita dapat menggunakan library untuk menambahkan navigation pada React App, library yang paling sering digunakan adalah React Router.

    Untuk menginstallnya eksekusi perintah berikut:

    1yarn add react-router-dom

    Konsep React Router

    Ada 3 komponen utama dalam React Router:

    • routers: <BrowserRouter> dan <HashRouter>
    • route matcher: <Route> dan <Switch>
    • navigation: <Link>, <NavLink>, <Redirect>

    Penjelasan singkat:

    • routers membuat component menjadi router component, jika kita ibaratkan component adalah kendaraan maka routers akan membuat sebuah rute yang bisa ditempuh oleh kendaraan tersebut
    • route matcher untuk mengarahkan ke component yang ingin dituju/dirender sesuai dengan URL, contoh:
    1<Route path="/add">
    2 <AddPage />
    3</Route>

    Pada code di atas jika kita akses alamat http://localhost:3000/add maka React Router akan mengarahkan ke component AddPage.

    • navigation, berfungsi seperti anchor link pada umumnya (seperti <a href>)

    Step by step

    1. Sekarang kita ubah code pada src/index.js menjadi:
    1import React from 'react';
    2import ReactDOM from 'react-dom';
    3import { BrowserRouter } from 'react-router-dom';
    4import './index.css';
    5import App from './App';
    6import * as serviceWorker from './serviceWorker';
    7
    8ReactDOM.render(
    9 <React.StrictMode>
    10 <BrowserRouter>
    11 <App />
    12 </BrowserRouter>
    13 </React.StrictMode>,
    14 document.getElementById('root')
    15);
    16
    17// If you want your app to work offline and load faster, you can change
    18// unregister() to register() below. Note this comes with some pitfalls.
    19// Learn more about service workers: https://bit.ly/CRA-PWA
    20serviceWorker.unregister();
    1. Buat Route untuk setiap page.

    src/App.js

    1import React from 'react';
    2import { Route, Switch } from 'react-router-dom';
    3import HomePage from './pages/Home';
    4import AddPage from './pages/Add';
    5import EditPage from './pages/Edit';
    6import './App.css';
    7
    8function App() {
    9 return (
    10 <div className="App">
    11 <Switch>
    12 <Route path="/add">
    13 <AddPage />
    14 </Route>
    15 <Route path="/edit">
    16 <EditPage />
    17 </Route>
    18 <Route path="/">
    19 <HomePage />
    20 </Route>
    21 </Switch>
    22 </div>
    23 );
    24}
    25
    26export default App;

    Yang perlu diperhatikan disini adalah untuk route ke Home page harus ditaruh dipaling akhir, karena react router akan memeriksa route secara berurutan dari atas ke bawah.

    Jadi jika kita menaruhnya di paling atas, semua akan diarahkan ke Home page.

    Sekarang setiap page memiliki alamatnya sendiri.

    5. Membuat Page Layout

    Masalah kedua dari aplikasi dinotes adalah adanya duplicate code.

    Jika diperhatikan component Header & Footer ada di setiap page.

    Meskipun sudah menjadi sebuah shared component, kita tetap harus menyisipkannya di setiap page.

    1...
    2<Header />
    3 <SharedComponent1 />
    4 <SharedComponent2 />
    5 <Page />
    6 <SharedComponent3 />
    7 <SharedComponent4 />
    8<Footer />
    9...

    Dan jika salah satu shared component tidak dibutuhkan lagi, maka shared component harus dihapus dari setiap page.

    Hal ini sedikit merepotkan.

    Untuk mengatasinya kita bisa membuat sebuah page layout, semua shared component di dalam page layout dapat digunakan oleh setiap page yang menggunakan layout ini.

    layout

    shared component

    Gambar di atas menunjukan bahwa jika sebuah shared component di dalam layout page diubah/edit maka perubahan juga terjadi di setiap page yang menggunakan layout tersebut.

    Step by step

    1. Buat sebuah folder baru bernama layouts dan sebuah file js PageLayout.js didalamnya
    1dinotes-app
    2 |--node_modules
    3 |--public
    4 |--src
    5 |--components
    6 |--shared
    7 |--Header.js
    8 |--Footer.js
    9 |--layouts
    10 |--PageLayout.js
    11 |--pages
    12 |--Home.js
    13 ...
    1. Salin code dibawah ini ke dalam PageLayout.js.
    1import React from 'react';
    2import Header from '../components/shared/Header';
    3import Footer from '../components/shared/Footer';
    4
    5const PageLayout = (props) => {
    6 const { children } = props;
    7
    8 return (
    9 <>
    10 <Header />
    11 {children}
    12 <Footer />
    13 </>
    14 );
    15};
    16
    17export default PageLayout;

    Kita menggunakan special props bernama children yang berfungsi untuk mewakili semua child component dari component PageLayout

    1. Ubah page Home, src/pages/Home.js menjadi:
    1import React from 'react';
    2import PageLayout from '../layouts/PageLayout';
    3
    4const NotesList = () => {
    5 return <div>Notes List</div>;
    6};
    7
    8const HomePage = () => {
    9 return (
    10 <PageLayout>
    11 <button>Add New Note</button>
    12 <NotesList />
    13 </PageLayout>
    14 );
    15};
    16
    17export default HomePage;

    Dengan ini kita cukup membuat shared component di dalam PageLayout.

    Semua page yang menggunakan PageLayout dapat menggunakan shared component yang baru dibuat.

    Sehingga tidak perlu lagi menambahkan shared component ke setiap page.

    1. Lakukan hal yang sama untuk page yang lain.

    src/pages/AddPage.js

    1import React from "react";
    2import PageLayout from "../layouts/PageLayout";
    3
    4const AddNoteForm = () => {
    5 return (
    6 <>
    7 <form>
    8 <label>
    9 Title:
    10 <input type="text" name="title" />
    11 </label>
    12 <label>
    13 Note:
    14 <textarea name="note" />
    15 </label>
    16 <button type="submit">Add</button>
    17 </form>
    18 </>
    19 );
    20};
    21
    22const AddPage = () => {
    23 return (
    24 <PageLayout>
    25 <h1>Add New Note</h1>
    26 <AddNoteForm />
    27 </PageLayout>
    28 );
    29};
    30
    31export default AddPage;

    src/pages/EditPage.js

    1import React from "react";
    2import PageLayout from "../layouts/PageLayout";
    3
    4const EditNoteForm = () => {
    5 return (
    6 <>
    7 <form>
    8 <label>
    9 Title:
    10 <input type="text" name="title" />
    11 </label>
    12 <label>
    13 Note:
    14 <textarea name="note" />
    15 </label>
    16 <button type="submit">Save</button>
    17 <button>Delete</button>
    18 </form>
    19 </>
    20 );
    21};
    22
    23const EditPage = () => {
    24 return (
    25 <PageLayout>
    26 <h1>Edit Note</h1>
    27 <EditNoteForm />
    28 </PageLayout>
    29 );
    30};
    31
    32export default EditPage;

    6. Styling

    Sekarang kita tambahkan CSS pada aplikasi DinoTes sebagai solusi untuk permasalahan yang ketiga yaitu tampilan yang tidak rapi.

    Kita akan menggunakan library styled-components.

    Step by step

    1. Install styled-components.
    1yarn add styled-components

    Style App Component

    App.js

    1import React from 'react';
    2import { Route, Switch } from 'react-router-dom';
    3import styled from 'styled-components';
    4import HomePage from './pages/Home';
    5import AddPage from './pages/Add';
    6import EditPage from './pages/Edit';
    7
    8const Container = styled.div`
    9 text-align: center;
    10`;
    11
    12function App() {
    13 return (
    14 <Container>
    15 <Switch>
    16 <Route path="/add">
    17 <AddPage />
    18 </Route>
    19 <Route path="/edit">
    20 <EditPage />
    21 </Route>
    22 <Route path="/">
    23 <HomePage />
    24 </Route>
    25 </Switch>
    26 </Container>
    27 );
    28}
    29
    30export default App;

    Pada code di atas kita buat sebuah styled component dengan nama Container.

    1. Delete App.css, karena sudah tidak diperlukan lagi.
    1. Tambahkan logo pada Header.

    Kita bebas memilih logo sesuai keinginan, untuk logo yang digunakan di materi ini bisa didownload disini

    1. Buat sebuah folder dengan nama assets dan subfolder images untuk menyimpan file logo.
    1dinotes-app
    2 |--node_modules
    3 |--public
    4 |--src
    5 |--assets
    6 |--images
    7 |--header-logo.png
    8 |--components
    9 |--shared
    10 |--Header.js
    11 |--Footer.js
    12 |--layouts
    13 |--PageLayout.js
    14 |--pages
    15 |--Home.js
    16 ...
    1. Edit src/components/shared/Header.js.
    1import React from 'react';
    2import styled from 'styled-components';
    3import logo from '../../assets/images/header-logo.png';
    4
    5const Container = styled.div`
    6 margin: 1rem;
    7 padding: 0.5rem;
    8`;
    9
    10const Header = () => {
    11 return (
    12 <Container>
    13 <img src={logo} alt="logo" />
    14 <h1>DinoTes App</h1>
    15 </Container>
    16 );
    17};
    18
    19export default Header;
    1. Edit src/components/shared/Footer.js.
    1import React from 'react';
    2import styled from 'styled-components';
    3
    4const Container = styled.div`
    5 margin: 1rem;
    6 padding: 0.5rem;
    7 min-height: 10vh;
    8`;
    9
    10const Footer = () => {
    11 return (
    12 <Container>
    13 <p>
    14 by <a href="https://devsaurus.com">devsaurus</a> &copy; 2020
    15 </p>
    16 </Container>
    17 );
    18};
    19
    20export default Footer;

    Style Home Page

    1. Edit src/pages/Home.js.
    1import React from 'react';
    2import styled from 'styled-components';
    3import PageLayout from '../layouts/PageLayout';
    4
    5const Container = styled.div`
    6 display: flex;
    7 flex-direction: column;
    8 align-items: center;
    9 justify-content: center;
    10 margin: 1rem;
    11`;
    12
    13const Button = styled.button`
    14 background: #3182ce;
    15 color: white;
    16 font-size: 1em;
    17 margin: 1rem 0;
    18 padding: 0.75rem;
    19 border: 2px solid white;
    20 border-radius: 5px;
    21`;
    22
    23const NotesList = styled.div`
    24 display: flex;
    25 flex-direction: column;
    26 min-width: 30vw;
    27 margin: 1rem;
    28 padding: 1rem;
    29 border: 2px solid #a0aec0;
    30 border-radius: 5px;
    31`;
    32
    33const HomePage = () => {
    34 return (
    35 <PageLayout>
    36 <Container>
    37 <Button>Add New Note</Button>
    38 <h1>All Notes</h1>
    39 <NotesList>All Notes</NotesList>
    40 </Container>
    41 </PageLayout>
    42 );
    43};
    44
    45export default HomePage;

    ✅ Hasil Akhir:

    homepage with style

    Style Add Page

    1. Edit src/pages/Add.js.
    1import React from 'react';
    2import styled from 'styled-components';
    3import PageLayout from '../layouts/PageLayout';
    4
    5const Container = styled.div`
    6 display: flex;
    7 flex-direction: column;
    8 align-items: center;
    9 justify-content: center;
    10 margin: 1rem;
    11`;
    12
    13const Form = styled.form`
    14 display: flex;
    15 flex-direction: column;
    16 min-width: 30vw;
    17 margin: 1rem;
    18`;
    19
    20const FormGroup = styled.div`
    21 display: flex;
    22 flex-direction: column;
    23`;
    24
    25const Label = styled.label`
    26 text-align: left;
    27 color: #4a5568;
    28`;
    29
    30const Input = styled.input`
    31 margin: 1rem 0;
    32 padding: 0.5rem;
    33`;
    34
    35const TextArea = styled.textarea`
    36 margin: 1rem 0;
    37 padding: 0.5rem;
    38 resize: none;
    39`;
    40
    41const Button = styled.button`
    42 background: #3182ce;
    43 color: white;
    44 font-size: 1em;
    45 margin: 1rem 0;
    46 padding: 0.75rem;
    47 border: 2px solid white;
    48 border-radius: 5px;
    49`;
    50
    51const AddNoteForm = () => {
    52 return (
    53 <Form>
    54 <FormGroup>
    55 <Label>Title</Label>
    56 <Input type="text" name="title" />
    57 </FormGroup>
    58 <FormGroup>
    59 <Label>Note</Label>
    60 <TextArea name="note" rows="12" />
    61 </FormGroup>
    62 <FormGroup>
    63 <Button type="submit">Add</Button>
    64 </FormGroup>
    65 </Form>
    66 );
    67};
    68
    69const AddPage = () => {
    70 return (
    71 <PageLayout>
    72 <Container>
    73 <h2>Add New Note</h2>
    74 <AddNoteForm />
    75 </Container>
    76 </PageLayout>
    77 );
    78};
    79
    80export default AddPage;

    ✅ Hasil Akhir:

    addpage with style

    Style Edit Page

    1. Edit src/pages/Edit.js.
    1import React from 'react';
    2import styled from 'styled-components';
    3import PageLayout from '../layouts/PageLayout';
    4
    5const Container = styled.div`
    6 display: flex;
    7 flex-direction: column;
    8 align-items: center;
    9 justify-content: center;
    10 margin: 1rem;
    11`;
    12
    13const Form = styled.form`
    14 display: flex;
    15 flex-direction: column;
    16 min-width: 30vw;
    17 margin: 1rem;
    18`;
    19
    20const FormGroup = styled.div`
    21 display: flex;
    22 flex-direction: column;
    23`;
    24
    25const Label = styled.label`
    26 text-align: left;
    27 color: #4a5568;
    28`;
    29
    30const Input = styled.input`
    31 margin: 1rem 0;
    32 padding: 0.5rem;
    33`;
    34
    35const TextArea = styled.textarea`
    36 margin: 1rem 0;
    37 padding: 0.5rem;
    38 resize: none;
    39`;
    40
    41const Button = styled.button`
    42 background: #3182ce;
    43 color: white;
    44 font-size: 1em;
    45 margin: 1rem 0;
    46 padding: 0.75rem;
    47 border: 2px solid white;
    48 border-radius: 5px;
    49`;
    50
    51const EditNoteForm = () => {
    52 return (
    53 <Form>
    54 <FormGroup>
    55 <Label>Title</Label>
    56 <Input type="text" name="title" />
    57 </FormGroup>
    58 <FormGroup>
    59 <Label>Note</Label>
    60 <TextArea name="note" rows="12" />
    61 </FormGroup>
    62 <FormGroup>
    63 <Button type="submit">Add</Button>
    64 <Button>Delete</Button>
    65 </FormGroup>
    66 </Form>
    67 );
    68};
    69
    70const EditPage = () => {
    71 return (
    72 <PageLayout>
    73 <Container>
    74 <h1>Edit Note</h1>
    75 <EditNoteForm />
    76 </Container>
    77 </PageLayout>
    78 );
    79};
    80
    81export default EditPage;

    ✅ Hasil Akhir:

    editpage with style


    Sekarang tampilan dari aplikasi DinoTes menjadi lebih rapi dari sebelumnya. Tetapi source code menjadi cukup panjang untuk setiap page-nya.

    Pada materi berikutnya kita akan lakukan Refactoring, menata ulang code agar lebih simple.