Terakhir diperbaharui: Dec 24, 2020
Search & Sorting
Fitur selanjutnya yang akan kita tambahkan ke aplikasi DinoTes adalah fitur Search & Sorting.
- Search, menambahkan sebuah search bar atau kolom pencarian untuk memudahkan user mencari note
- Sorting, menambahkan sebuah menu dropdown agar user bisa mengurutkan note berdasarkan waktu terakhir note diupdate
Kedua fitur ini bisa ditambahkan tanpa menginstall library external / third party.
Search
Untuk membuat fitur ini kita akan gunakan konsep filtering, yaitu menampilkan note yang mengandung kata yang sama dengan kata kunci atau keyword yang dimasukan oleh user.
Gambar
Persiapan
Clone repository dari aplikasi DinoTes disini.
Install dependency dengan jalankan perintah yarn install
atau npm install
.
Step by Step
Membuat Search Bar
Buat sebuah component search bar atau kolom pencarian pada halaman utama aplikasi.
1const SearchBar = tw.input`2 my-4 p-23 text-left4 border rounded5 focus:outline-none focus:ring focus:border-blue-300`;
Tempatkan SearchBar tepat di atas component NotesListContainer.
src/components/NotesList.js
1...2 return (3 <>4 <SearchBar placeholder='Search Notes...' />5 <NotesListContainer>{content}</NotesListContainer>6 </>7 );8...
Karena jumlah component lebih dari satu maka tempatkan SearchBar dan NotesListContainer dalam satu container.
1...2 return (3 <Container>4 <SearchBar placeholder='Search Notes...' />5 <NotesListContainer>{content}</NotesListContainer>6 </Container>7 );8...
Hasilnya
Update slice
Karena aplikasi DinoTes menggunakan Redux, kita perlu menambahkan sebuah function pada file slice yang bertugas untuk melakukan filter terhadap data notes.
Tambahkan function berikut pada file src/features/notes/notesSlice.js:
1export const getFilteredNotes = (state, keyword) => {2 if (keyword) {3 const isKeywordExist = (array, string) => array.toLowerCase().includes(string);45 return state.notes.data.filter((note) => isKeywordExist(note.note, keyword) || isKeywordExist(note.title, keyword));6 }7 return state.notes.data;8};
Function di atas akan melakukan pengecekan apakah keyword yang dicari bisa ditemukan di dalam judul atau isi dari note.
Update NotesList.js
Langkah terakhir adalah menambahkan handler dan update function getAllNotes dengan function getFilteredNotes.
src/components/NotesList.js
1import React, { useEffect, useState } from 'react';2import tw from 'twin.macro';3import { Link } from 'react-router-dom';4import { useSelector, useDispatch } from 'react-redux';5import { fetchNotes, getFilteredNotes } from '../features/notes/notesSlice';6import Container from './ui/Container';78const NotesListContainer = tw.div`grid grid-cols-1 md:grid-cols-3 gap-4 my-8`;9const Card = tw.div`text-left p-4 border rounded-md`;10const Title = tw.h4`text-lg font-semibold text-purple-900`;11const SearchBar = tw.input`my-4 p-2 text-left border rounded focus:outline-none focus:ring focus:border-blue-300`;1213const NotesList = () => {14 const [keyword, setKeyword] = useState('');15 const dispatch = useDispatch();16 const notes = useSelector((state) => getFilteredNotes(state, keyword));17 const notesStatus = useSelector((state) => state.notes.status);18 const error = useSelector((state) => state.notes.error);1920 useEffect(() => {21 if (notesStatus === 'idle') {22 dispatch(fetchNotes());23 }24 }, [notesStatus, dispatch]);2526 const handleChange = (e) => {27 setKeyword(e.target.value);28 };2930 let content;3132 if (notesStatus === 'loading') {33 content = <div>Loading...</div>;34 } else if (notesStatus === 'succeeded') {35 content = notes.map((note) => {36 return (37 <Card key={note._id}>38 <Title>39 <Link to={`/edit/${note._id}`}>{note.title}</Link>40 </Title>41 <p>{note.note.slice(0, 101)}</p>42 </Card>43 );44 });45 } else if (notesStatus === 'failed') {46 content = <div>{error}</div>;47 }4849 return (50 <Container>51 <SearchBar placeholder="Search Notes..." onChange={handleChange} />52 <NotesListContainer>{content}</NotesListContainer>53 </Container>54 );55};5657export default NotesList;
Hasil Akhir: