IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 【React】React全家桶之React哲学 -> 正文阅读

[JavaScript知识库]【React】React全家桶之React哲学


参考链接
React 哲学官方文档

刚使用React的同学有一个通病:拿到UI图后,没有任何思考和设计就去写,想到什么写什么,不合理的代码会出现很多bug,没错说的就是我自己~~~,那么我们就需要学习一下React哲学,看看别人是如何思考构建页面的。

React哲学会引导我们思考如何构建一个应用 , 倡导我们把代码写得更加简洁清晰,更具模块化,这一点在写大型的项目尤为重要,在写代码之前就把大致的结构和涉及的数据结构设计好,会减少 Bug 的产生,减少重构的时间,减少维护的成本。

准备阶段

在我们写代码之前 ,一定需要UI产品设计图后端接口数据

UI产品设计图

在这里插入图片描述

后端接口数据

[
  {category: "Sporting Goods", price: "$49.99", stocked: true, name: "Football"},
  {category: "Sporting Goods", price: "$9.99", stocked: true, name: "Baseball"},
  {category: "Sporting Goods", price: "$29.99", stocked: false, name: "Basketball"},
  {category: "Electronics", price: "$99.99", stocked: true, name: "iPod Touch"},
  {category: "Electronics", price: "$399.99", stocked: false, name: "iPhone 5"},
  {category: "Electronics", price: "$199.99", stocked: true, name: "Nexus 7"}
];

第一步:通过UI产品设计图划分组件层级

理清UI产品设计图的需求:

  • 一个展示商品的列表
  • 对商品进行关键字搜索,点击复选框展示商品现货,
  • 商品列表包含商品名和价格,商品支持分类显示,其中告罄的商品名为红色显示

划分组件层级:

  • 在设计稿上用方框圈出每一个组件(包括它们的子组件),并且以合适的名称命名(很关键)
  • 将组件当作JS函数考虑,一个组件原则上只能负责一个功能,如果组件功能较多,可以考虑将它拆分成更小的组件
  • UI应与数据模型一一对应 , 若将 UI 分离为组件,其中每个组件需与数据模型的某部分匹配。

不同的颜色划分成不同的组件,可以分成五部分:

  1. FilterableProductTable (橙色): 是整个示例应用的整体
  2. SearchBar (蓝色):接受所有的用户输如
  3. ProductTable (绿色): 展示数据内容并根据用户输入筛选结果
  4. ProductCategoryRow (天蓝色): 为每一个产品类别展示标题
  5. ProductRow (红色): 每一行展示一个产品

在这里插入图片描述

组件的层级划分:

  • FilterableProductTable
    • SearchBar
    • ProductTable
      • ProductCategoryRow
      • ProductRow

第二步:用React构建静态页面

编写应用:将编写静态页面和添加交互这两过程分开, 这是因为编写静态页面时需要大量代码,而添加交互时则要考虑大量细节, 将这两个过程分开进行更为合适 ,整个思路也比较清晰。

通过复用编写的组件,使用 props 来进行数据的传递,父组件把数据进行层层的传递,在这个过程中先不使用 state ,因为 state 表示的是会随着时间变化而变化的,所以在交互的过程中使用 。

props和state的区别:

  • props 是传递给组件的(类似于函数的形参),是父组件向子组件传递数据的方式
  • state 是在组件内被组件自己管理的(类似于在一个函数内声明的变量), 代表了随时间会产生变化的数据,应当仅在实现交互时使用
  • 组件可以选择把它的 state 作为 props 向下传递到它的子组件中

构建应用的方法:

  • 自上而下的方法:先写层级最高的组件,如FilterableProductTable 组件,这种比较适合简单的应用
  • 自下而上的方法:先写层级最低的组件,如 ProductRow组件,这种方法比较适合大型的应用构建

静态页面代码示例

// 后端接口JSON数据
const PRODUCTS = [
  {category: 'Sporting Goods', price: '$49.99', stocked: true, name: 'Football'},
  {category: 'Sporting Goods', price: '$9.99', stocked: true, name: 'Baseball'},
  {category: 'Sporting Goods', price: '$29.99', stocked: false, name: 'Basketball'},
  {category: 'Electronics', price: '$99.99', stocked: true, name: 'iPod Touch'},
  {category: 'Electronics', price: '$399.99', stocked: false, name: 'iPhone 5'},
  {category: 'Electronics', price: '$199.99', stocked: true, name: 'Nexus 7'}
];

// 根组件
const FilterableProductTable = () => (
  <div>
    <SearchBar />
    // 给产品列表组件传JSON数据
    <ProductTable products={PRODUCTS} />
  </div>
);

// 搜索组件
const SearchBar = () => (
  <form>
    <input type="text" placeholder="Search..." />
    <p>
      <input type="checkbox" /> Only show products in stock
    </p>
  </form>
);

// 产品列表组件
const ProductTable = ({ products }) => { //从props解构出products(JSON数据)
  const rows = [];
  let lastCategory = null;

  products.forEach((product) => {
    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>
  );
};

// 产品类别标题组件
const ProductCategoryRow = ({ category }) => (
  <tr>
    <td colSpan="2">{category}</td>
  </tr>
);

// 每一行展示一个产品组件
const 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>
  );
};

第三步:确定 state 的最小且完整的集合

想要使你的 UI 具备交互功能,需要有触发基础数据改变的能力 ,React 通过实现 state 来完成这个任务。

state 是在组件内被组件自己管理的(类似于在一个函数内声明的变量), 代表了随时间会产生变化的数据,应当仅在实现交互时使用 。

看一下当前应用有哪些数据

  • 商品的原始数据
  • 用户的搜索数据
  • 复选框是否选中的值
  • 经过筛选后的数据

通过问自己以下三个问题,你可以逐个检查相应数据是否属于 state

  • 数据是否能通过 props 来传递
  • 是否会通过时间而产生改变
  • 是否可以通过其他 state和props计算得到

最后确认,原始数据可以通过 props传递,用户搜索的数据和复选框的值可以作为 state ,筛选后的数据可以通过原始数据和用户搜索数据以及复选框数据计算得来。

最后 state是

  • 用户的搜索数据
  • 复选框是否选中的值

第四步:确定 state 放置的位置

确定 state 放置的位置:

  • React是自上而下的单的数据流,我们应把 state写在这些 state 的组件的共同父组件中
  • 如果你找不到一个合适的位置来存放该 state,就可以直接创建一个新的组件来存放该 state,并将这一新组件置于高于共同所有者组件层级的位置。

第五步:添加反向数据流

当我们要通过层级较低的组件改变层级较高的组件,就需要通过反向数据流的方式。

React中的反向数据流是需要高层级组件通过 props把改变 state的方法 (回调函数) 传递给低层级组件,低层次组件state改变后将值传给回调函数。

数据驱动UI: 组件化的框架就是数据驱动UI的 ,操作由React完成,你只需关注数据, 因为数据和UI之间建立了联系,通过操作这个数据,UI就能够自动进行变化。

const FilterableProductTable = () => {
  const [filterText, setFilterText] = React.useState("");
  const [inStockOnly, setInStockOnly] = React.useState(false);

  return (
    <div>
      <SearchBar
        filterText={filterText}
        setFilterText={setFilterText}
        inStockOnly={inStockOnly}
        setInStockOnly={setInStockOnly}
      />
      <ProductTable
        products={PRODUCTS}
        inStockOnly={inStockOnly}
        filterText={filterText}
      />
    </div>
  );
};

const SearchBar = ({
  filterText,
  setFilterText,
  inStockOnly,
  setInStockOnly,
}) => {
  const handleProductsSearch = (value) => {
    setFilterText(value);
  };

  const handleStockCheck = (value) => {
    setInStockOnly(value);
  };

  return (
    <form>
      <input
        type="text"
        placeholder="Search..."
        value={filterText}
        onChange={handleProductsSearch}
      />
      <p>
        <input
          type="checkbox"
          value={inStockOnly}
          onChange={handleStockCheck}
        />{" "}
        Only show products in stock
      </p>
    </form>
  );
};

const ProductTable = ({ products, inStockOnly, filterText }) => {
  const rows = [];
  let lastCategory = null;

  products.forEach((product) => {
    if (product.name.indexOf(filterText) === -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>
  );
};

最后:需要明白组件拆分与封装

组件拆分:组件拆分需要考虑布局和交互。需要整体考虑布局和交互,把它的特性分析完毕后,再去考虑拆分。 理解组件化的时候,分析清楚所有的特性,布局特性、交互特性、数据特性,分析完整之后你再去设计,否则会导致你思考出来的拆分可能有问题。拆分有问题,就会导致你实现起来很困难。

组件封装: 把重复出现多的地方进行封装,把共性(一样)的东西封装成组件或者函数,把差异性(不一样)的东西设计成参数。然后差异性的参数与函数里的共性部分组合起来,完成组件封装。

组件封装的作用

  • 简化代码提高可读性
  • 通过共性和差异性封装,提高代码复用
  • 维护时逻辑清晰,修复时快速定位问题源头。
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-07-20 18:43:07  更:2022-07-20 18:45:27 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 21:49:29-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码