Merapihkan dan menyederhanan code
Buat file baru di folder Common dengan nama Table.jsx
Table.jsx
import React from "react";
import TableHeader from '../tableHeader'
import TableBody from '../tableBody';
const Table = ({ columns, sortColumn, onSort, data}) => {
return (
<table className="table">
<TableHeader
columns={columns}
sortColumn={sortColumn}
onSort={onSort}
/>
<TableBody columns={columns} data={data}/>
</table>
);
}
export default Table;
Setelah itu ubah code di file moviesTable.jsx
import React, { Component } from 'react';
import Table from './Common/Table';
import Like from './Common/Like';
// const x = <Like></Like>;
class MoviesTable extends Component {
columns = [
{ path: 'title', label: 'Title' },
{ path: 'genre.name', label: 'Genre' },
{ path: 'numberInStock', label: 'Stock' },
{ path: 'dailyRentalRate', label: 'Rate' },
{ key: "like",
content: movie => <Like liked={movie.liked} onClick={() => this.props.onLike(movie)} />
},
{ key: "delete",
content: movie => (
<button
onClick={() => this.props.onDelete(movie)}
className="btn btn-danger btn-sm">
Delete
</button>
)
}
]
render(){
const { movies, onSort, sortColumn } = this.props;
return (
<Table
columns={this.columns}
data={movies}
sortColumn={sortColumn}
onSort={onSort}
/>
)
}
}
export default MoviesTable
Dan ubah jg file tableBody.jsx
import React, { Component } from "react";
import _ from 'lodash';
class TableBody extends Component {
renderCell = (item, column) => {
if(column.content) return column.content(item);
return _.get(item, column.path);
}
createKey = (item, column) => {
return item._id + (column.path || column.key);
}
render() {
const { data, columns } = this.props;
return(
<tbody>
{data.map(item => (
<tr key={item._id}>
{columns.map(column => (
<td key={this.createKey(item, column)}>
{ this.renderCell(item, column) }
</td>
))}
</tr>
))}
</tbody>
)
}
}
export default TableBody
tableHeader.jsx
import React, { Component } from "react";
// colums: array
// sortColumn: object
// onSort: function
class TableHeader extends Component {
raiseSort = path => {
const sortColumn = { ...this.props.sortColumn };
if(sortColumn.path === path)
sortColumn.order = sortColumn.order === "asc" ? "desc" : "asc";
else {
sortColumn.path = path;
sortColumn.order = "asc";
}
this.props.onSort(sortColumn);
}
renderSortIcon = column => {
const { sortColumn } = this.props;
if (column.path !== this.props.sortColumn.path) return null;
if (this.props.sortColumn.order === 'asc') return <i className="fa fa-sort-asc" />;
return <i className="fa fa-sort-desc" />
};
render() {
return (
<>
<thead>
<tr>
{ this.props.columns.map(column => (
<th
className="clickable"
key={column.path || column.key }
onClick={() => this.raiseSort(column.path)}
>
{ column.label } { this.renderSortIcon(column) }
</th>
)) }
</tr>
</thead>
</>
)
}
}
export default TableHeader;
movies.jsx
import React, {Component} from 'react';
import ListGroup from './Common/listGroup';
import Pagination from './Common/Pagination';
import MoviesTable from './moviesTable';
import { getMovies } from '../services/fakeMovieService';
import { getGenres } from '../services/fakeGenreService';
import { paginate } from '../utils/paginate';
import _ from 'lodash';
class Movies extends Component {
state = {
movies: [],
genres: [],
currentPage: 1,
pageSize: 4,
sortColumn: { path: "title", order: "asc" }
};
componentDidMount() {
const genres = [{ _id: "", name: 'All Genres'}, ...getGenres() ]
this.setState({ movies: getMovies(), genres });
}
handleDelete = movie => {
const movies = this.state.movies.filter(m => m._id !== movie._id);
this.setState({ movies })
// console.log(movie)
}
handleLike = movie => {
const movies = [...this.state.movies];
const index = movies.indexOf(movie);
movies[index] = { ...movies[index] };
movies[index].liked = !movies[index].liked;
this.setState({ movies });
// console dan ambil tiap data per id
// console.log("like bos", movie)
}
handlePageChange = page => {
this.setState({ currentPage: page });
// console.log(page)
}
handleGenreSelect = genre => {
this.setState({ selectedGenre: genre, currentPage: 1 })
}
handleSort = sortColumn => {
this.setState({ sortColumn })
// console.log(path)
}
getPagedData = () => {
const {
pageSize,
currentPage,
sortColumn,
selectedGenre,
movies: allMovies
} = this.state;
const filtered =
selectedGenre && selectedGenre._id
? allMovies.filter(m => m.genre._id === selectedGenre._id)
: allMovies;
const sorted = _.orderBy(filtered, [sortColumn.path], [sortColumn.order]);
const movies = paginate(sorted, currentPage, pageSize);
return { totalCount: filtered.length, data:movies }
}
render() {
const { lenght: count } = this.state.movies;
const { pageSize, currentPage, sortColumn } = this.state;
if( count === 0)
return <p>There are no movies in the database</p>;
const { totalCount, data: movies } = this.getPagedData();
return (
<>
<div className="row">
<div className="col-3">
<ListGroup
items={this.state.genres}
selectedItem={this.state.selectedGenre}
onItemSelect={this.handleGenreSelect}
/>
</div>
<div className="col">
<p>Showing {totalCount} movies in the database</p>
<MoviesTable
movies={movies}
sortColumn={sortColumn}
onLike={this.handleLike}
onDelete={this.handleDelete}
onSort={this.handleSort}
/>
<Pagination
itemsCount={totalCount}
pageSize={pageSize}
currentPage={currentPage}
onPageChange={this.handlePageChange}
/>
</div>
</div>
</>
)
}
}
export default Movies
Codingan lebih sederhana dan terpisah pisah file nya, hasil nya pun akan tetap sama
Contoh code:
Last updated
Was this helpful?