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

React 编程思想 #2

时间:2023-03-31 17:13:16浏览次数:37  
标签:状态 product 编程 思想 FilterableProductTable React 组件 filterText SearchBar

React 编程思想 #2

接上文,已经实现了一个静态的页面,现在就要给页面加上交互了。

寻找 State

状态是应用需要记录的最小变化,构建状态的最重要的原则是 DRY(Don’t Repeat Yourself,不要重复自己)。对于一个应用,构建出它的状态的绝对最小表示,并通过这些状态计算其他需要的内容。例如,如果您正在构建一个购物列表,则可以将项目存储为状态中的数组。如果您还想显示列表中的项数,请不要将项数存储为另一个状态值,而是读取数组的长度。

以上来自 React 的官方文档对状态的定义,简单来说,状态是组件中不可计算的变量,当这些变量改变时,需要动态改变页面的内容,即重新渲染页面。

现在回想示例程序中的所有数据:

  • 原始的产品列表;
  • 用户输入的搜索文本;
  • 单选框的值;
  • 经过筛选的产品列表;

这里面哪些属于状态?状态需要满足以下要求:

  • 随着时间推移,它会发生改变;
  • 它不能是由父组件通过 props 传递来的;
  • Don’t Repeat Yourself,它不应该能从任何地方计算出来;

按照这个要求,我们可以进行筛选:

  • 原始的产品列表是由 props 传递的,所以它不是状态;
  • 用户输入的搜索文本会随着时间改变(用户改变),并且无法根据任何内容进行计算;
  • 单选框的值会随着时间改变(用户改变),并且无法根据任何内容进行计算;
  • 经过筛选的产品列表可以由原始的产品列表、单选框的值、输入的搜索文本计算出来(筛选),因此它也不是状态;

所以,只有搜索文本和单选框的值才是状态,Nice Done!

React 中有两种类型的“模型”数据:props 和 state。两者区别很大:
props 就像传递给函数的参数。它们允许父组件将数据传递给子组件并自定义其外观。例如,Form 可以将颜色 props 传递给 Button。
state 就像一个组件的内存。它允许组件跟踪一些信息,并根据交互对其进行更改。例如,按钮可能会跟踪 isHovered 状态。
props 和 state 是不同的,但它们是协同工作的。父组件通常会将一些信息保持在 state (可以进行改变),并将其作为子组件的 state 传递给子组件。如果第一次阅读时仍然感觉不清楚,那也没关系。它需要一点练习才能真正坚持下来!

决定 State 的位置

在确定了应用的状态后,还需要确定哪个组件负责拥有和更改这些状态。记住:React使用单向数据流,数据自顶向下流动,数据从父组件向下传递到子组件。目前可能还不清楚哪个组件应该拥有什么状态,如果你是这个概念的新手,这可能很有挑战性,但可以按照以下步骤来解决:

对于应用中的每个状态:

  1. 识别基于该状态呈现某些内容的每个组件;

  2. 找到它们最接近的公共父组件————在层次结构中位于它们之上的组件。

  3. 决定这个组件所在的位置:

通常,可以将状态直接放入它们的公共父级中,也可以将状态放入其公共父级之上的某个组件中。

如果找不到拥有状态的组件,请创建一个仅用于保存状态的新组件,并将其添加到公共父组件上方层次结构中的某个位置。

现在回到这个例子中的状态,决定它们的位置:

识别使用状态的组件:

  • ProductTable 需要根据该状态(搜索文本和单选框的值)筛选产品列表。

  • SearchBar 需要显示该状态(搜索文本和单选框的值)。

找到它们的共同父组件:两个组件共享的第一个父组件是 FilterableProductTable。

决定状态的位置:可以在 FilterableProductTable 中保存搜索文本和单选框的状态值。

因此,状态值将存在于 FilterableProductTable 中,代码如下:

  function FilterableProductTable({ products }) {
    const [filterText, setFilterText] = React.useState('');
    const [inStockOnly, setInStockOnly] = React.useState(false);

这里需要提一下,useState 方法只在 React 16.8 版本以上存在,由于我之前使用的是 16.4 版本,这地方一直报错方法不存在,研究了半天才发现问题。

接着,将 State filterText 和 inStockOnly 作为 props 传递给 ProductTable 和 SearchBar:

function FilterableProductTable({ products }) {
  const [filterText, setFilterText] = useState('');
  const [inStockOnly, setInStockOnly] = useState(false);

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

当 filterText 或 inStockOnly 状态改变时(用户进行了操作),拥有这些状态的组件 FilterableProductTable 会感知到状态的变化,重新渲染页面内容;又因为 ProductTable 和 SearchBar 组件在 FilterableProductTable 组件中,同时接收了这两个状态作为 props,它们也会重新渲染。这样,ProductTable 和 SearchBar 就可以根据状态更改自身显示的内容了。

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>
  );
}

function SearchBar({ filterText, inStockOnly }) {
  return (
    <form>
      <input 
        type="text" 
        value={filterText} 
        placeholder="Search..."/>
      <label>
        <input 
          type="checkbox" 
          checked={inStockOnly} />
        {' '}
        Only show products in stock
      </label>
    </form>
  );
}

其中,SearchBar 组件根据这两个状态,更改页面上显示的内容;ProductTable 组件根据这两个状态,重新计算经过筛选的产品列表,如此便实现了页面的动态变化。

添加反向数据流

目前,应用已经通过自顶向下流动的 props 和 state 进行了正确的渲染。但是,要想根据用户输入更改状态,还需要支持数据以另一种方式流动:位于层次结构中下方的表单组件需要更新 FilterableProductTable 中的状态。

React明确地规定了数据流动的方式,但相比于双向数据绑定,它需要更多的输入(代码编写)。如果尝试在上面的组件构成的页面中输入搜索内容或改变单选框,可以看到输入没有响应,被 React 忽略了。这是故意的(

标签:状态,product,编程,思想,FilterableProductTable,React,组件,filterText,SearchBar
From: https://www.cnblogs.com/qiyuanc/p/Front7.html

相关文章

  • 通过MapEdit源程序的学习MAP文件 3, 改编程序,没有编辑功能,只显示MAP
    unitshowmap;interfaceusesWindows,Messages,SysUtils,Variants,Classes,Graphics,Controls,Forms,Dialogs,ExtCtrls,StdCtrls,WIL,ComCtrls;constUNITX=48;UNITY=32;typeTMapInfo=packedrecord//这个好像不需要PACKED......
  • 前端React框架和jsx语法的编码规范
    基本规则(BasicRules)每个文件只包含一个React组件然而,在一个文件里包含多个没有state或纯组件是允许的。eslint:react/no-multi-comp.经常用JSX语法。不要用React.createElement,除非你从一个非JSX文件中初始化app。ClassvsReact.createClassvsstateless......
  • C语言编程练习_查找数组中不重复的数字
    题目描述:给定一个整形数组空间arr,数据中包含两个一样的数字若干,只有一个数字是单独一个。设计一个函数把这个出现一次的数字返回出来。 解决方案一:穷举法:假设arr数组中的每个元素都是重复的。也可能是不重复的(效率差)#include<stdio.h>intfun1(intarr[],intlen){  ......
  • vue或者react中的hooks的理解
    我们听过react里面有hooks的概念,那么怎么理解hooks呢? 其实vue2中,我们没有hooks的概念,vue3中我们引入了组合式函数(也就是用组合式api写的),它其实就是vue的hooks。 总结下来,hooks有以下特点:1、hooks其实就是个函数,只是实现它的方法比较特殊,利用组合式api实现的。2、组合式函......
  • c++ 多线程编程std::thread, std::shared_mutex, std::unique_lock
    在C++11新标准中,可以简单通过使用thread库,来管理多线程,使用时需要#include<thread>头文件。简单用例如下:1std::thread(Simple_func);2std::threadt(Simple_func);3t.detach();第一行是直接启动一个新线程来执行Simple_func函数,而第二行先声明一个线程函数t(返回类型为......
  • Twitter营销教程_编程入门自学教程_菜鸟教程-免费教程分享
    教程简介IT宝库整理的推特营销入门教程-从基本到高级概念简单步骤的Twitter营销,包括概述,帐户和个人资料,追随者,普通推文,图像和视频帖子,可嵌入推文,Hashtags,转发,列表,有用功能,Twitter搜索,Twitter卡,定义策略,声誉管理,管理转换,自动化,本地分析,HootSuite。教程目录Twitter营销教程Tw......
  • unity学习——c#初级编程
    1.作为行为组件的脚本首先新建一个cube立方体  然后新建一个c#脚本,脚本用来实现立方体cube的三种颜色变化(按键实现)  脚本代码如下:usingUnityEngine;usingSystem.Collections;publicclasscolor:MonoBehaviour{voidUpdate(){if(Input.GetKeyD......
  • 3.30App端地铁查询 设计思路 源程序代码、运行结果截图、编程总结分析。
    App端地铁查询设计思路源程序代码、运行结果截图、编程总结分析。 关于地铁查询App的设计思路。设计思路:我们沿用pc端的数据库设计结构,减少了我们的工作量。查询方法以及设计思路都很javaweb设计的大同小异。在设计中我们遇到的主要问题就是安卓Studio中的mysql数据库的......
  • React 笔记
    Date:2023-03-3020:36:05视频链接:尚硅谷React教程开始学react了,......
  • react useComparedState
    import{useCallback,useRef,useState}from'react';import{shallowEqual}from"../utils/shallowEqual";functionuseComparedState(initialState:any){const[state,setState]=useState(initialState);conststateRef=useRef......