Terakhir diperbaharui: Oct 24, 2020
Membuat Front End #2
Daftar Isi
4. Membuat Navigasi Component 5. Membuat Page Layout 6. Styling - Style App Component - Style Header Footer - Style Home Page - Style Add Page - Style Edit Page4. Membuat Navigasi Component
Kita akan menyelesaikan masalah yang ada pada bagian sebelumnya yaitu:
- Semua page ditampilkan dalam satu page, diakses dengan satu alamat
- Duplicate code
- 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
- 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';78ReactDOM.render(9 <React.StrictMode>10 <BrowserRouter>11 <App />12 </BrowserRouter>13 </React.StrictMode>,14 document.getElementById('root')15);1617// If you want your app to work offline and load faster, you can change18// unregister() to register() below. Note this comes with some pitfalls.19// Learn more about service workers: https://bit.ly/CRA-PWA20serviceWorker.unregister();
- 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';78function 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}2526export 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.
- page Home diakses dengan alamat http://localhost:3000
- page Add diakses dengan alamat http://localhost:3000/add
- page Edit diakses dengan alamat http://localhost:3000/edit
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.
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
- Buat sebuah folder baru bernama layouts dan sebuah file js PageLayout.js didalamnya
1dinotes-app2 |--node_modules3 |--public4 |--src5 |--components6 |--shared7 |--Header.js8 |--Footer.js9 |--layouts10 |--PageLayout.js11 |--pages12 |--Home.js13 ...
- Salin code dibawah ini ke dalam PageLayout.js.
1import React from 'react';2import Header from '../components/shared/Header';3import Footer from '../components/shared/Footer';45const PageLayout = (props) => {6 const { children } = props;78 return (9 <>10 <Header />11 {children}12 <Footer />13 </>14 );15};1617export default PageLayout;
Kita menggunakan special props bernama children yang berfungsi untuk mewakili semua child component dari component PageLayout
- Ubah page Home, src/pages/Home.js menjadi:
1import React from 'react';2import PageLayout from '../layouts/PageLayout';34const NotesList = () => {5 return <div>Notes List</div>;6};78const HomePage = () => {9 return (10 <PageLayout>11 <button>Add New Note</button>12 <NotesList />13 </PageLayout>14 );15};1617export 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.
- Lakukan hal yang sama untuk page yang lain.
src/pages/AddPage.js
1import React from "react";2import PageLayout from "../layouts/PageLayout";34const 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};2122const AddPage = () => {23 return (24 <PageLayout>25 <h1>Add New Note</h1>26 <AddNoteForm />27 </PageLayout>28 );29};3031export default AddPage;
src/pages/EditPage.js
1import React from "react";2import PageLayout from "../layouts/PageLayout";34const 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};2223const EditPage = () => {24 return (25 <PageLayout>26 <h1>Edit Note</h1>27 <EditNoteForm />28 </PageLayout>29 );30};3132export 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
- 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';78const Container = styled.div`910`;1112function 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}2930export default App;
Pada code di atas kita buat sebuah styled component dengan nama Container.
- Delete App.css, karena sudah tidak diperlukan lagi.
Style Header Footer
- Tambahkan logo pada Header.
Kita bebas memilih logo sesuai keinginan, untuk logo yang digunakan di materi ini bisa didownload disini
- Buat sebuah folder dengan nama assets dan subfolder images untuk menyimpan file logo.
1dinotes-app2 |--node_modules3 |--public4 |--src5 |--assets6 |--images7 |--header-logo.png8 |--components9 |--shared10 |--Header.js11 |--Footer.js12 |--layouts13 |--PageLayout.js14 |--pages15 |--Home.js16 ...
- Edit src/components/shared/Header.js.
1import React from 'react';2import styled from 'styled-components';3import logo from '../../assets/images/header-logo.png';45const Container = styled.div`678`;910const Header = () => {11 return (12 <Container>13 <img src={logo} alt="logo" />14 <h1>DinoTes App</h1>15 </Container>16 );17};1819export default Header;
- Edit src/components/shared/Footer.js.
1import React from 'react';2import styled from 'styled-components';34const Container = styled.div`5678`;910const Footer = () => {11 return (12 <Container>13 <p>14 by <a href="https://devsaurus.com">devsaurus</a> © 202015 </p>16 </Container>17 );18};1920export default Footer;
Style Home Page
- Edit src/pages/Home.js.
1import React from 'react';2import styled from 'styled-components';3import PageLayout from '../layouts/PageLayout';45const Container = styled.div`67891011`;1213const Button = styled.button`1415161718192021`;2223const NotesList = styled.div`2425262728293031`;3233const 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};4445export default HomePage;
✅ Hasil Akhir:
Style Add Page
- Edit src/pages/Add.js.
1import React from 'react';2import styled from 'styled-components';3import PageLayout from '../layouts/PageLayout';45const Container = styled.div`67891011`;1213const Form = styled.form`1415161718`;1920const FormGroup = styled.div`212223`;2425const Label = styled.label`262728`;2930const Input = styled.input`313233`;3435const TextArea = styled.textarea`36373839`;4041const Button = styled.button`4243444546474849`;5051const 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};6869const AddPage = () => {70 return (71 <PageLayout>72 <Container>73 <h2>Add New Note</h2>74 <AddNoteForm />75 </Container>76 </PageLayout>77 );78};7980export default AddPage;
✅ Hasil Akhir:
Style Edit Page
- Edit src/pages/Edit.js.
1import React from 'react';2import styled from 'styled-components';3import PageLayout from '../layouts/PageLayout';45const Container = styled.div`67891011`;1213const Form = styled.form`1415161718`;1920const FormGroup = styled.div`212223`;2425const Label = styled.label`262728`;2930const Input = styled.input`313233`;3435const TextArea = styled.textarea`36373839`;4041const Button = styled.button`4243444546474849`;5051const 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};6970const EditPage = () => {71 return (72 <PageLayout>73 <Container>74 <h1>Edit Note</h1>75 <EditNoteForm />76 </Container>77 </PageLayout>78 );79};8081export default EditPage;
✅ Hasil Akhir:
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.