在本篇技术博客中,我们将介绍React官方示例:React哲学。我们将深入探讨这个示例中使用的组件化、状态管理和数据流等核心概念。让我们一起开始吧!
项目概览
React是一个流行的JavaScript库,用于构建用户界面。React的设计理念是通过组件化构建复杂的UI界面,使得代码更加模块化、可维护和可复用。
在React哲学示例中,我们创建了一个简单的可过滤的产品表格。这个示例涉及到以下组件:
FilterableProductTable
组件:作为整个应用的容器组件,包含了搜索栏和产品表格组件。SearchBar
组件:用于接收用户输入的搜索关键字和过滤条件,并通过回调函数更新父组件的状态。ProductTable
组件:展示产品表格,根据用户输入的搜索关键字和过滤条件进行过滤。ProductCategoryRow
组件:用于显示产品表格中的产品类别行。ProductRow
组件:用于显示产品表格中的每一行产品。
FilterableProductTable
组件
FilterableProductTable
组件作为整个应用的容器组件,代码如下:
import { useState } from 'react';
function FilterableProductTable({ products }) {
const [filterText, setFilterText] = useState('');
const [inStockOnly, setInStockOnly] = useState(false);
return (
<div>
<SearchBar
filterText={filterText}
inStockOnly={inStockOnly}
onFilterTextChange={setFilterText}
onInStockOnlyChange={setInStockOnly} />
<ProductTable
products={products}
filterText={filterText}
inStockOnly={inStockOnly} />
</div>
);
}
FilterableProductTable
组件接收一个products
数组作为props,表示要展示的产品列表。在FilterableProductTable
组件内部,我们使用了useState
钩子来管理搜索关键字filterText
和是否仅显示有库存产品inStockOnly
的状态。
FilterableProductTable
组件包含了SearchBar
组件和ProductTable
组件。通过props
将状态和处理函数传递给子组件,实现子组件与父组件之间的通信。
SearchBar
组件
SearchBar
组件用于接收用户输入的搜索关键字和过滤条件,并通过回调函数更新父组件的状态。代码如下:
function SearchBar({
filterText,
inStockOnly,
onFilterTextChange,
onInStockOnlyChange
}) {
return (
<form>
<input
type="text"
value={filterText} placeholder="Search..."
onChange={(e) => onFilterTextChange(e.target.value)} />
<label>
<input
type="checkbox"
checked={inStockOnly}
onChange={(e) => onInStockOnlyChange(e.target.checked)} />
{' '}
Only show products in stock
</label>
</form>
);
}
SearchBar
组件接收filterText
和inStockOnly
作为props,表示当前的搜索关键字和是否仅显示有库存产品的状态。同时,还接收了两个回调函数onFilterTextChange
和onInStockOnlyChange
,用于在用户输入或选择过滤条件时更新父组件的状态。
在SearchBar
组件的JSX中,我们使用了一个文本输入框和一个复选框,分别用于输入搜索关键字和选择是否只显示有库存产品。通过onChange
事件处理函数,将用户输入的值传递给父组件。
ProductTable
组件
ProductTable
组件用于展示产品表格,并根据用户输入的搜索关键字和过滤条件进行过滤。代码如下:
function ProductTable({ products, filterText, inStockOnly }) {
const rows = [];
let lastCategory = null;
products.forEach((product) => {
if (
product.name.toLowerCase().indexOf(
filterText.toLowerCase()
) === -1
) {
return;
}
if (inStockOnly && !product.stocked) {
return;
}
if (product.category !== lastCategory) {
rows.push(
<ProductCategoryRow
category={product.category}
key={product.category} />
);
}
rows.push(
<ProductRow
product={product}
key={product.name} />
);
lastCategory = product.category;
});
return (
<table>
<thead>
<tr>
<th>Name</th>
<th>Price</th>
</tr>
</thead>
<tbody>{rows}</tbody>
</table>
);
}
ProductTable
组件接收products
数组、filterText
和inStockOnly
作为props。在ProductTable
组件内部,我们根据用户输入的搜索关键字和过滤条件对产品列表进行过滤,然后生成相应的产品表格行。
在遍历products
数组时,我们首先根据搜索关键字进行过滤,如果产品的名称不包含搜索关键字,则跳过该产品。接着,根据是否只显示有库存产品进行过滤,如果选中了“只显示有库存产品”,但当前产品没有库存,则同样跳过该产品。最后,根据产品的类别来判断是否需要添加产品类别行。
ProductCategoryRow
组件和 ProductRow
组件
ProductCategoryRow
组件和ProductRow
组件分别用于显示产品表格中的产品类别行和每一行产品。它们的代码如下:
function ProductCategoryRow({ category }) {
return (
<tr>
<th colSpan="2">
{category}
</th>
</tr>
);
}
function ProductRow({ product }) {
const name = product.stocked ? product.name :
<span style={{ color: 'red' }}>
{product.name}
</span>;
return (
<tr>
<td>{name}</td>
<td>{product.price}</td>
</tr>
);
}
ProductCategoryRow
组件接收category
作为props,表示产品的类别名称。它会在表格中添加一个合并了两列的单元格,用于显示产品类别名称。
ProductRow
组件接收product
作为props,表示单个产品的信息。根据产品是否有库存,我们使用条件渲染来决定是否添加样式,并根据产品名称显示不同的文本颜色。
Login
组件
最后,我们在Login
组件中导入了示例数据PRODUCTS
,并将其传递给FilterableProductTable
组件作为products
props。代码如下:
const PRODUCTS = [
{ category: "Fruits", price: "$1", stocked: true, name: "Apple" },
{ category: "Fruits", price: "$1", stocked: true, name: "Dragonfruit" },
{ category: "Fruits", price: "$2", stocked: false, name: "Passionfruit" },
{ category: "Vegetables", price: "$2", stocked: true, name: "Spinach" },
{ category: "Vegetables", price: "$4", stocked: false, name: "Pumpkin" },
{ category: "Vegetables", price: "$1", stocked: true, name: "Peas" }
];
export default function Login() {
return <FilterableProductTable products={PRODUCTS} />;
}
Login
组件简单地将示例数据PRODUCTS
传递给FilterableProductTable
组件,实现了整个应用的渲染。
效果:
总结
在这篇技术博客中,我们深入探讨了React官方示例:React哲学。我们学习了React的核心概念,如组件化、状态管理和数据流,并通过一个简单的可过滤产品表格示例进行了实践。