在本篇技术博客中,我们将介绍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><SearchBarfilterText={filterText}inStockOnly={inStockOnly}onFilterTextChange={setFilterText}onInStockOnlyChange={setInStockOnly} /><ProductTableproducts={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><inputtype="text"value={filterText} placeholder="Search..."onChange={(e) => onFilterTextChange(e.target.value)} /><label><inputtype="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(<ProductCategoryRowcategory={product.category}key={product.category} />);}rows.push(<ProductRowproduct={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的核心概念,如组件化、状态管理和数据流,并通过一个简单的可过滤产品表格示例进行了实践。