這章節將透過篩選欄位來過濾符合條件的資料
其實在篩選條件的原理上和新增大同小異,都是對資料列表做出對應的改動,但比較不同的是,篩選時我們一般不會直接改動原資料,而是透過 Array.filter()
來產生一組符合條件的資料列表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| function Expenses(props) { const [filteredYear, setFilteredYear] = useState("2020");
const filterExpenses = props.item.filter((item) => item.date.getFullYear() === +filteredYear);
return ( {filterExpenses.map((expense) => ( <ExpenseItem key={expense.id} title={expense.title} amount={expense.amount} date={expense.date} ></ExpenseItem> ))} ); }
|
無資料預設內容
一般在介面設計上,無倫是圖片或是文字內容,在沒有取得資料時常會有預設內容以提升使用體驗,在這個範例中我們可以在判斷該年度沒有取得資料時,填入一段預設文字,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| function Expenses(props) { const [filteredYear, setFilteredYear] = useState("2020");
const filterExpenses = props.item.filter((item) => item.date.getFullYear() === +filteredYear);
return ( {filterExpenses.length === 0 ? ( <p>No expenses found.</p> ) : ( filterExpenses.map((expense) => ( <ExpenseItem key={expense.id} title={expense.title} amount={expense.amount} date={expense.date} ></ExpenseItem> )) )} ); }
|
又或者可以透過 JavaScript &&
來改寫,當判斷第一個條件為 true
時,就顯示第二個條件的結果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| return ( ... {filterExpenses.length === 0 && <p>No expenses found.</p>} {filterExpenses.length > 0 && filterExpenses.map((expense) => ( <ExpenseItem key={expense.id} title={expense.title} amount={expense.amount} date={expense.date} ></ExpenseItem> )) } ... );
|
區分 JS 邏輯與 HTML 頁面
這樣的寫法有一個問題是,隨著我們開發內容不斷增加,如果把過多的邏輯都寫到 return
中,就會讓程式碼看起來相對複雜一點,為了避免這個情況,我們可以將邏輯從 return
中抽離到 Component Function ; 在 React 中,有一個比較特別的用法是,JSX 其實不只可以寫在 return
內,還可以讓它作為一個變數的值來儲存,透過這個功能我們就可以輕易地將邏輯獨立出來
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| function Expenses(props) { const [filteredYear, setFilteredYear] = useState("2020");
const filterExpenses = props.item.filter((item) => item.date.getFullYear() === +filteredYear);
let expenseContent = <p>No expenses found.</p>;
if (filterExpenses.length > 0) { expenseContent = filterExpenses.map((expense) => ( <ExpenseItem key={expense.id} title={expense.title} amount={expense.amount} date={expense.date} ></ExpenseItem> )); }
return ( ... {expenseContent} ... ); }
|
Adding Conditional Return Statements
我們可以進一步將這些內容抽離出成為一個 Component ExpenseList,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| import ExpenseList from './ExpenseList';
function Expenses() { ... return { <ExpenseList items={filteredExpenses}/> }; }
import ExpenseItem from "./ExpenseItem";
function ExpenseList(props) { return ( <ul> {props.items.map((expense) => ( <ExpenseItem key={expense.id} title={expense.title} amount={expense.amount} date={expense.date} ></ExpenseItem> ))} </ul> ); }
export default ExpenseList;
|
但這裡有一個比較特別的做法是,因為 Component 抽離使的功能更加單純,所以先前透過判斷資料列表沒有資料時,所做的預設內容可以直接在條件符合時將之回傳
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| function ExpenseList(props) { if (props.items.length === 0) { return <h2 className="expenses-list__fallback">Found no expenses.</h2>; } return ( <ul className="expense-list"> {props.items.map((expense) => ( <ExpenseItem key={expense.id} title={expense.title} amount={expense.amount} date={expense.date} ></ExpenseItem> ))} </ul> ); }
|
資料參考
React - The Complete Guide (Incl Hooks, React Router, Redux)