首页 > 编程语言 >React 编程思想 #1

React 编程思想 #1

时间:2023-03-30 18:14:05浏览次数:40  
标签:category stocked name 思想 price 编程 React 组件

React 编程思想 #1

看太多语法,都不如简单尝试一下,跟着官方文档做了一下 DEMO,文档写的真不错,就是没翻译完,一大半都还是英文(×_×),本篇其实大部分也是在重复文档内容,不过加上了自己的尝试。

从原型开始

React 可以改变你对所看到的设计以及所构建的应用程序的看法。以前你看到的是一片森林,使用 React 后,你将欣赏到每一棵树。React 简化了你对设计系统(design system)和 UI 状态的看法。在本教程中,我们将带领你使用 React 构建一个可搜索的数据表产品,并领略整个思考的过程。

以上来自 React 的官方文档(https://react.bootcss.com/learn/thinking-in-react#),形容的可以说是非常好了。React 的编程思想就是如何从控件(树)到应用(森林)。

首先假设开发界面时已经拥有了 API 返回的数据(或者模拟出来的):

[
  { 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" }
]

同时也有了设计师设计的原型,原型中除了对数据的显示,还要有搜索栏和单选框实现过滤的需求:

有了这两个东西,就可以进行代码的设计了。首先,从构建 UI 开始,按照 React 的思想,需要将 UI 细分成多个组件,文档中的分法是分成了五个组件:

这五个组件是:

  1. FilterableProductTable (灰色部分)包含了整个应用程序。
  2. SearchBar (蓝色部分)接收用户输入。
  3. ProductTable (紫色部分)根据用户的输入显示和筛选列表。
  4. ProductCategoryRow (绿色部分)显示每个类别的标题。
  5. ProductRow (黄色部分)每行显示一个产品。

根据组件之间的包含关系,可以区分出它们的层级:

  • ——FilterableProductTable
  • ————SearchBar
  • ————ProductTable
  • ——————ProductCategoryRow
  • ——————ProductRow

划分了界面的组件和组件关系后,就可以进行编码了。

静态实现

首先进行界面的静态实现,即简单显示内容,不包含交互操作。React 构建的应用,画面由组件转换为 HTML 代码渲染出来(不知道的话先看入门把 https://react.bootcss.com/learn),因此,可以将一个个组件理解为一段段的 HTML 代码块。父组件包含子组件,就好像 HTML 标签之间的嵌套。这里的思想和 DOM 的思想是一样的(我是这么认为的,不一定对哈)。

对于简单的应用,自顶向下构建组件更加简单,而复杂的应用自底向上构建组件更加简单。这个 DEMO 自然是简单的应用,因此直接从最大的组件 FilterableProductTable 开始构建:

  function FilterableProductTable({products}) {
    return (
      <div>
        <SearchBar />
        <ProductTable products={products} />
      </div>
    );
  }

分析一下这段代码,整体看这段代码是一个 JS 函数,返回了一段 HTML 代码,这就是一个组件了;其中,包含了两个子组件 SearchBarProductTable,与上面划分的组件结构一致;这个函数的参数是 {products},即商品列表,在后面,又将这个参数传递给了 ProductTable,这也是 React 的一个特点:数据自顶向下流动,即数据由父组件传递给子组件。

多说一句,这里参数传递的方式是 {products},加上了花括号,因为如果没有花括号,React 会认为这是一整个 props 属性,如这样:

  // 不加花括号,传递的是 props,后续还要在 props 中获取 products
  function FilterableProductTable(props) {
    return (
      <div>
        <SearchBar />
        <ProductTable products={props.products} />
      </div>
    );
  } 

继续其他组件的构建,这里就不多说了,最后构建出的整个 JS 文件如下:


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>
    );
  }
  
  function ProductTable({ products }) {
    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>
    );
  }
  
  function SearchBar() {
    return (
      <form>
        <input type="text" placeholder="Search..." />
        <label>
          <input type="checkbox" />
          {' '}
          Only show products in stock
        </label>
      </form>
    );
  }

  function FilterableProductTable({products}) {
    return (
      <div>
        <SearchBar />
        <ProductTable products={products} />
      </div>
    );
  }
  
  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"}
  ];
  
 function App() {
    return <FilterableProductTable products={PRODUCTS} />;
  }

可以看到,组件之间的关系和之前划分的组件结构一致,父组件包含着子组件,子组件之间也可能是兄弟,和 HTML 标签之间的关系是一致的。

SearchBar 组件中,显示了搜索框和单选框,没有其他的子组件,但也仅仅是显示,还没有交互的功能;ProductTable 组件是一个表格,其中,包含了多个 ProductRowProductCategoryRow 组件,这两个组件即商品行和商品目录行,其内容是根据参数 products 进行动态渲染的。

最后,构建了一个 APP 组件,包含了最大的组件 FilterableProductTable 并第一次传递了参数 PRODUCTS,这就是应用(森林)了。

构建完应用后,还需要将其渲染到页面上,参考代码如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello Qiyuanc!</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
<script type="text/babel" src="./reactTest2.js"></script>
</head>
<body>

<div id="example"></div>

<script type="text/babel">

    ReactDOM.render(<App />, document.getElementById('example'))

</script>

</body>
</html>

reactTest2.js 文件就是上面构建的应用所在的文件,通过引入 React 和这个 JS 文件,可以使用 ReactDOM.render 方法将其渲染到页面上的占位符 example 上(这就是基础了,不多说)。

这里踩到个坑:在 VSCode 中启动 HTML 页面,会报错 CORS(跨域访问错误),这是由于 HTML 页面是通过 file:// 访问的,JS 文件也是通过 file:// 访问的,触发了浏览器的安全保护策略。在研究了半天后,发现可以通过搭建服务器,转换为 http:// 访问解决。但因为一些特殊原因,我这用不了 npm,装不了 http-server,很搞。还好最后在 VSC 里发现了个插件 Live Server,可以直接转换为本地服务器启动,最终也是起起来了。

最后实现的效果就是这样啦:

在本地跑起来感觉还是不一样的。

标签:category,stocked,name,思想,price,编程,React,组件
From: https://www.cnblogs.com/qiyuanc/p/Front6.html

相关文章

  • 什么?又来智能AI编程?让不让我们活了!
    无事逛github发现了一款智能AI编程,故下载试试发现异常好用推荐给大家github地址:GitHub-getcursor/cursor:一个用于使用AI......
  • Java并发编程——Thread详解
    前言操作系统中,一个进程往往代表着一个应用程序实例,而线程是进程中轻量级的调度单元,也可以看作是轻量级的进程,可以共享进程资源。下面简单介绍在操作系统中线程通用实现方式。接下来内容主要对线程模型进行简单介绍,然后对Java线程实现Thread类进行了解。一、线程模型暂且抛开Jav......
  • Java 8 函数式编程
    1Java8函数式编程2java.util.function.*3@FunctionalInterface4都是函数接口,没有成员(状态)56高阶函数:参数或返回值为函数78方法引用:类名::方法......
  • Mybatis面向切面编程(AOP)的applicationContext配置文件
    面向切面编程(AOP)applicationContext.xml配置文件<?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="http://www.springframework.org/schema/beans" xmlns:xsi="ht......
  • Tiggzi:甩了其它小白编程工具N条街的移动应用开发工具
    如今有许多小白编程工具,但总体来说,有太多局限性,要建立复杂专业的应用,就只能望洋兴叹,但今天要介绍的Tiggzi却能帮你建立更复杂更专业的应用,并且能将API连接作为插件重新使用......
  • Java异步编程CompletableFuture
    Java通过多线程可以实现异步编程,下面是一个使用Java多线程实现异步编程的示例:publicclassAsyncDemo{publicstaticvoidmain(String[]args){Exec......
  • golang并发编程-模式
    1.Generator9.Queuepackagemainimport("fmt""sync""time")constlimit=4constwork=100funcprocess(wg*sync.WaitGroup,workint,......
  • Python编程必不可少的pytest测试框架
    进行编程测试重要的是为了更高效的完成功能的实现。pytest是基于unittest实现的第三方测试框架,比unittest更加的简洁、高效,并且可以完美兼容unittest的测试代码,无需对......
  • 西门子S7-1200PLC结构化编程5轴伺服项目
    西门子S7-1200PLC结构化编程5轴伺服项目项目实现功能:1.三轴机械手X轴-Y轴-Z轴联动取放料PTO脉冲定位控制台达B2伺服2.台达伺服速度模式应用+扭矩模式应用实现收放卷3.......
  • 选择Kendo React PDF查看器的几个理由,一定要看!
    KendoUI致力于新的开发,来满足不断变化的需求,通过React框架的KendoUIJavaScript封装来支持ReactJavascript框架。KendoUIforReact能够为客户提供更好的用户体验,并且......