【React】React学习:从初级到高级(一)

这篇具有很好参考价值的文章主要介绍了【React】React学习:从初级到高级(一)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1 UI描述

1.1 组件的创建与使用

组件是用户界面UI的构成要素。创建一个组件可以分为三步:

1.1.1 创建组件

  1. 导出组件

    • export default
  2. 定义函数

    • function name(props) {}

    • 定义组件的时候,组件的名称必须以大写字母开头,否则将无法运行。

      HTML标签是小写的

  3. 添加标签

    • JSX(使用JavaScript)

    • TSX(使用TypeScript)

    • 注意:如果标签和return 不在同一行,则必须把它包裹在一堆括号中,

      没有括号包裹的话,任何在return 下一行的代码都将被忽略!

1.1.2 使用组件

在父组件中引入即可,但是不要在组件中定义组件。应该在顶层定义组件。当子组件需要使用父组件的数据时,需要 通过 props 的形式进行传递,而不是嵌套定义。

1.2 组件的导入与导出

1.2.1 根组件文件

相当于把所有模块化组件做一个集成的文件。


1.2.2 导出和导入一个组件

对组件进行拆分可以分为三步:

  1. 创建一个新的JS文件来存放该组件
  2. 导出该文件中的函数组件(可以使用默认导出或者具名导出
  3. 在需要使用该组件的文件中导入(可以根据相应的导出的方式使用默认导入或者具名导入
语法 导出语句 导入语句
默认 export default function Hello() {} import Hello from './Hello.js';
具名 export function Hello() {} import { Hello } from './Hello.js';

注意:在引入一些文件时虽然没有添加.js文件名后缀,比如./Hello.js还是./HelloReact里都能正常使用,只是前者更符合原生ES模块

一个文件里有且仅有一个默认导出,但是可以有任意多个具名导出。组件的导出方式决定了其导入方式。通常,文件中仅包含一个组件时,会选择默认导出,而当文件中包含多个组件或某个值需要导出时,则会选择具名导出。


1.2.3 从同一文件中导出和导入多个组件

同一文件中,有且仅有一个默认导出,但可以有多个具名导出!

1.3 使用JSX书写标签语言

JSX是JavaScript语法扩展,可以在JavaScript文件中写类似HTML的标签。(虚拟DOM)

1.3.1 JSX:将标签引入JavaScript

**在 React 中,渲染逻辑和标签共同存在于同一个地方——组件。**将一个按钮的渲染逻辑和标签放在一起可以确保它们在每次编辑时都能保持互相同步。每个 React 组件都是一个 JavaScript 函数,它会返回一些标签,React 会将这些标签渲染到浏览器上。

JSX React 是相互独立的东西。JSX 是一种语法扩展,而 React 则是一个 JavaScript 的库。


1.3.2 将HTML转换为JSX

JSX规则:

  1. 只能返回一个根元素

    • 如果想要在一个组件中包含多个元素,需要用一个父标签把它们包裹起来

    • 如果不想在标签中增加一个额外的 <div>,可以用 <></> 元素来代替:

      这个空标签被称作 Fragment. React Fragment 允许将子元素分组,而不会在 HTML 结构中添加额外节点。

    为什么多个 JSX 标签需要被一个父元素包裹?

    答:JSX 虽然看起来很像 HTML,但在底层其实被转化为了 JavaScript 对象,你不能在一个函数中返回多个对象,除非用一个数组把他们包装起来。这就是为什么多个 JSX 标签必须要用一个父元素或者 Fragment 来包裹。

  2. 标签必须闭合

  3. 使用驼峰式命名法给大部分属性命名

    • 由于历史原因,aria-*data-* 属性是以带 - 符号的 HTML 格式书写的。

1.3.3 高级提示:使用JSX转化器

将HTML转换为JSX:https://transform.tools/html-to-jsx


1.4 在JSX中通过大括号使用JavaScript

1.4.1 使用引号传递字符串

想把一个字符串属性传递给 JSX 时,把它放到单引号或双引号中

若想要动态指定可以使用{}

大括号内的任何JavaScript表达式都可以正常运行。

在 JSX 中,只能在以下两种场景中使用大括号:

  1. 用作 JSX 标签内的文本<h1>{name}'s To Do List</h1> 是有效的,但是 <{tag}>Gregorio Y. Zara's To Do List</{tag}> 无效。
  2. 用作紧跟在 = 符号后的 属性src={avatar} 会读取 avatar 变量,但是 src="{avatar}" 只会传一个字符串 {avatar}

1.4.2 使用"双大括号":JSX中的CSS和对象

对象也用大括号表示,例如 { name: "无敌是多么寂寞", inventions: 5 }。因此,为了能在 JSX 中传递,你必须用另一对额外的大括号包裹对象:person={{ name: "无敌是多么寂寞", inventions: 5 }}

import { getImageUrl } from './utils.js'

const person = {
  name: 'Gregorio Y. Zara',
  imageId: '7vQD0fP',
  imageSize: 's',
  theme: {
    backgroundColor: 'black',
    color: 'pink'
  }
};

export default function TodoList() {
  return (
    <div style={person.theme}>
      <h1>{person.name}'s Todos</h1>
      <img
        className="avatar"
        src={getImageUrl(person)}
        alt={person.name}
      />
      <ul>
        <li>Improve the videophone</li>
        <li>Prepare aeronautics lectures</li>
        <li>Work on the alcohol-fuelled engine</li>
      </ul>
    </div>
  );
}

// 将获取图片的语句封装成一个函数
export function getImageUrl(person) {
  return (
    'https://i.imgur.com/' +
    person.imageId +
    person.imageSize +
    '.jpg'
  );
}


1.5 将Props传递给组件

React 组件使用 props 来互相通信。每个父组件都可以提供 props 给它的子组件,从而将一些信息传递给它。Props 可能会让你想起 HTML 属性,但你可以通过它们传递任何 JavaScript 值,包括对象、数组和函数

1.5.1 将Props传递给组件

父组件可以分两步将props传递给子组件

  1. 首先在父组件中将props传递给引用的子组件,使得子组件可以读取这些props

  2. 在子组件中读取props,这些 props 在 ({}) 之间,并由逗号分隔。比如

    function Avatar({ person, size }) {
      // 在这里 person 和 size 是可被子组件访问的
    }
    

props 正是 组件的唯一参数! React 组件函数接受一个参数,一个 props 对象。比如:

function Avatar(props) {
  let person = props.person;
  let size = props.size;
  // ...
}

1.5.2 给props指定一个默认值

如果想在没有指定值的情况下给 prop 一个默认值,可以通过在参数后面写 = 默认值来进行解构,比如:

function Avatar({ person, size = 100 }) {
  // ...
}

但是如果传递了 size={null}size={0},默认值将 被使用。

1.5.3 使用JSX展开语法传递props

先看两段代码感受一下

// 第一段
function Profile({ person, size, isSepia, thickBorder }) {
  return (
    <div className="card">
      <Avatar
        person={person}
        size={size}
        isSepia={isSepia}
        thickBorder={thickBorder}
      />
    </div>
  );
}
// 第二段
function Profile(props) {
  return (
    <div className="card">
      <Avatar {...props} />
    </div>
  );
}

是不是觉得第二段用了展开语法的代码更简洁!但是这通常表示你应该拆分组件了,并需要将子组件作为JSX传递。

1.5.4 将JSX作为子组件传递

当将内容嵌套在 JSX 标签中时,父组件将在名为 children 的 prop 中接收到该内容。

function Card({ children }) {
  return (
    <div className="card">
      {children}
    </div>
  );
}

export default function Profile() {
  return (
    <Card>
       <h1>哎哟不错哦</h1>
    </Card>
  );
}

可以将带有 children prop 的组件看作有一个“洞”,可以由其父组件使用任意 JSX 来“填充”。

1.5.5 props如何随时间变化

**一个组件可能会随着时间的推移收到不同的 props。**但是props的改变是父组件通过传递不同的props——新对象来改变的。旧props会被丢弃然后被JS引擎回收它们占用的内存.当需要交互性时,可以设置 state

1.6 条件渲染

1.6.1 条件返回JSX

可以用if else、&&、? :语句来写分支逻辑

1.6.2 选择性地返回null

例如:

function Item({ name, isPacked }) {
  if (isPacked) {
    return null;
  }
  return <li className="item">{name}</li>;
}

export default function PackingList() {
  return (
    <section>
      <h1>Sally Ride 的行李清单</h1>
      <ul>
        <Item 
          isPacked={true} 
          name="宇航服" 
        />
        <Item 
          isPacked={true} 
          name="带金箔的头盔" 
        />
        <Item 
          isPacked={false} 
          name="Tam 的照片" 
        />
      </ul>
    </section>
  );
}

实际上,在组件里返回 null 并不常见。通常情况下,可以在父组件里选择是否要渲染该组件。

选择性地包含JSX

可以使用三目运算符? :。如果代码有小段重复可以考虑用这个进行简单的条件判断。比如:

// 修改前
if (isPacked) {
  return <li className="item">{name}</li>;
}
return <li className="item">{name}</li>;

// 修改后
return (
  <li className="item">
    {isPacked ? name + ' ✔' : name}
  </li>
);

或者用&&运算符

  return (
    <li className="item">
      {name} {isPacked && '✔'}
    </li>
  );

与表达式的判定若为false,React会将其视为控制,不会对其进行任何渲染。但切勿把数字放在&&左侧,因为如果左侧是0,React会渲染0

选择性地将JSX赋值给变量

结合if语句和let赋值变量可以更加灵活。因为可以使用 let 进行重复赋值,所以一开始可以将想展示的(这里指的是物品的名字)作为默认值赋予给该变量。

function Item({ name, isPacked }) {
  let itemContent = name;
  if (isPacked) {
    itemContent = name + " ✔";
  }
  return (
    <li className="item">
      {itemContent}
    </li>
  );
}

export default function PackingList() {
  return (
    <section>
      <h1>Sally Ride 的行李清单</h1>
      <ul>
        <Item 
          isPacked={true} 
          name="宇航服" 
        />
        <Item 
          isPacked={true} 
          name="带金箔的头盔" 
        />
        <Item 
          isPacked={false} 
          name="Tam 的照片" 
        />
      </ul>
    </section>
  );
}

1.7 渲染列表

操作数组中的数据,将一个数据集渲染成多个相似的组件。

1.7.1 从数组中渲染数据

利用map()函数

const people = [
  '凯瑟琳·约翰逊: 数学家',
  '马里奥·莫利纳: 化学家',
  '穆罕默德·阿卜杜勒·萨拉姆: 物理学家',
  '珀西·莱温·朱利亚: 化学家',
  '苏布拉马尼扬·钱德拉塞卡: 天体物理学家',
];

export default function List() {
  const listItems = people.map(person =>
    <li>{person}</li>
  );
  return <ul>{listItems}</ul>;
}

注意:这里还未给每个数据加上唯一标识符key

1.7.2 对数组项进行过滤

先利用filter()函数进行筛选,再利用map()函数进行渲染

import { people } from './data.js';
import { getImageUrl } from './utils.js';

export default function List() {
  const chemists = people.filter(person =>
    person.profession === '化学家'
  );
  const listItems = chemists.map(person =>
    <li>
      <img
        src={getImageUrl(person)}
        alt={person.name}
      />
      <p>
        <b>{person.name}:</b>
        {' ' + person.profession + ' '}{person.accomplishment}而闻名世界
      </p>
    </li>
  );
  return <ul>{listItems}</ul>;
}

注意:这里还未给每个数据加上唯一标识符key.

箭头函数会隐式地返回位于 => 之后的表达式,所以可以省略 return 语句。不过,如果 => 后面跟了一对花括号 { ,那必须使用 return 来指定返回值! 箭头函数 => { 后面的部分被称为 “块函数体”,块函数体支持多行代码的写法,但要用 return 语句才能指定返回值。


1.7.3 用key保持列表项的顺序

必须给数组中的每一项都指定一个 key——它可以是字符串或数字的形式,只要能唯一标识出各个数组项就行。

直接放在 map() 方法里的 JSX 元素一般都需要指定 key 值!

一个合适的 key 可以帮助 React 推断发生了什么,从而得以正确地更新 DOM 树。

如果想让每个列表项都输出多个 DOM 节点而非一个的话,只能要么把生成的节点用一个 <div> 标签包裹起来,要么使用长一点但更明确的 <Fragment> 写法:

import { Fragment } from 'react';

// ...

const listItems = people.map(person =>
  <Fragment key={person.id}>
    <h1>{person.name}</h1>
    <p>{person.bio}</p>
  </Fragment>
);

这里的 Fragment 标签本身并不会出现在 DOM 上,这串代码最终会转换成 <h1><p><h1><p>…… 的列表。

key值的设定:

  • 来自数据库的数据:可以直接使用数据表中的主键
  • 本地产生数据:可以使用一个自增计数器或者一个类似 uuid 的库来生成 key。

key需要满足的条件

  • key 值在兄弟节点之间必须是唯一的。 不过不要求全局唯一,在不同的数组中可以使用相同的 key。
  • key 值不能改变。不要在运行过程中动态地产生 key。

React之所以需要key值,是因为即使元素的位置在渲染的过程中发生了改变,它提供的 key 值也能让 React 在整个生命周期中一直认得它。

注意,组件不会把 key 当作 props 的一部分。Key 的存在只对 React 本身起到提示作用。如果你的组件需要一个 ID,那么请把它作为一个单独的 prop 传给组件: <Profile key={id} userId={id} />

挑战题:

请根据给你的数组生成菜谱列表!其中每个菜谱,都用 <h2> 来显示它的名称,并在 <ul> 里列出它所需的原料。

data.js

export const recipes = [
  {
    id: 'greek-salad',
    name: '希腊沙拉',
    ingredients: ['西红柿', '黄瓜', '洋葱', '油橄榄', '羊奶酪'],
  },
  {
    id: 'hawaiian-pizza',
    name: '夏威夷披萨',
    ingredients: ['披萨饼皮', '披萨酱', '马苏里拉奶酪', '火腿', '菠萝'],
  },
  {
    id: 'hummus',
    name: '鹰嘴豆泥',
    ingredients: ['鹰嘴豆', '橄榄油', '蒜瓣', '柠檬', '芝麻酱'],
  },
];

App.js

import { recipes } from './data.js';

function RecipeShow({ recipesList }) {
  return (
    <div>
      {recipesList.map(recipe =>
        <div key={recipe.id}>
          <h2>{recipe.name}</h2>
          <ul>
            {recipe.ingredients.map(ingredent => 
             <li key={ingredent}>
                {ingredent}
              </li>
            )}  
          </ul>
        </div>
        )}
    </div>
  )
}

function Card({children}) {
  return (
    <div>{ children }</div>
  )
}

export default function RecipeList() {
  return (
    <Card>
      <div>
        <h1>菜谱</h1>
        <RecipeShow recipesList={recipes} />
      </div>
    </Card>
  );
}

1.8 保持组件为纯函数

一个React组件,不管什么时候给了它一个相同的输入,那么它的输出就是相同的,就像数学公式一样。比如y=2x,无论何时传x=3,其输出总是y=6

React 无法保证组件函数以任何特定的顺序执行,因此无法通过设置变量在它们之间进行通信。所有的交流都必须通过 props 进行。

1.8.1 局部mutation

我们将组件改变了预先存在的变量的值的现象称为突变(mutation)。局部突变的意思就是在渲染时更改刚刚创建的变量和对象,属于内部突变,不会影响函数外部的变量或函数。

但是事件处理程序无需是纯函数,包括更新屏幕、启动动画、更改数据等。

React为何侧重于纯函数?文章来源地址https://www.toymoban.com/news/detail-684789.html

  1. 复用性,适应不同环境
  2. 可以缓存纯函数的输出来跳过渲染,提高性能
  3. 在渲染深层组件树的过程中,如果数据发生了变化,可以随时安全停止计算,节省时间。

到了这里,关于【React】React学习:从初级到高级(一)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 前端框架之争:Vue.js vs. React.js vs. Angular

    🎉欢迎来到Web前端专栏~前端框架之争:Vue.js vs. React.js vs. Angular ☆* o(≧▽≦)o *☆嗨~我是IT·陈寒🍹 ✨博客主页:IT·陈寒的博客 🎈该系列文章专栏:架构设计 📜其他专栏:Java学习路线 Java面试技巧 Java实战项目 AIGC人工智能 数据结构学习 🍹文章作者技术和水平有限,如果

    2024年02月07日
    浏览(93)
  • 如何使用前端框架(React、Angular、Vue.js等)?该如何选择?

    聚沙成塔·每天进步一点点 前端入门之旅:探索Web开发的奇妙世界 欢迎来到前端入门之旅!感兴趣的可以订阅本专栏哦!这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发者,这里都将为你提供一个系统而

    2024年02月07日
    浏览(61)
  • 前端刷新页面的五种方法(含原生js、vue和react)

    1、window.history.go(0)方法 2、location.reload()方法 3、location.href=location.href方法 4、vue-router方法 5、react-router方法

    2024年02月16日
    浏览(51)
  • 前端框架学习-React(一)

    React 应用程序是由 组件 组成的。 react 程序是用的jsx语法,使用这种语法的代码需要由babel进行解析,解析成js代码。 jsx语法: 只能返回一个根元素 所有的标签都必须闭合(自闭和或使用一对标签的方式闭合) 使用驼峰式命名法给大部分属性命名如:className 大写字母开头的

    2024年02月12日
    浏览(42)
  • 【学习前端第七十四课】React生命周期

    我们这里所说的生命周期是基于类式组件的,其中主要分为三个阶段 挂载 更新 卸载 以上每一个阶段内都有自己的一系列在当前生命周期中可被自动执行的生命周期函数(类似于vue的钩子函数) 挂载阶段(初始化) 在挂载阶段按照执行顺序分别有以下几个生命周期函数 co

    2024年02月21日
    浏览(45)
  • 丁鹿学堂:前端学习进阶指南之react入门(react在html中使用数据绑定和修改)

    在html中使用react 今天跟大家分享react的基础语法。 我们采用最简单的方法,就是在html中引入react 因为一上来就使用脚手架的话,很多配置大家不一定清楚。 而在html中使用react的话,可以直接去学习react最基本的语法。 这是零基础学习react的最佳实践。 引入react的依赖 react也

    2024年02月14日
    浏览(63)
  • 【前端】html2canvas生成图片空白排查data:;(js vue react uniapp)

    因为要做一个分享图,就用到了html2canvas,一开始是好好的,今天随便测了下,发现图片显示不出来了。打印了下,生成的图片链接变成了 data:; 。后面一步一步地排查,发现是页面内容太多了,删减一点内容就能显示出来。然后我又去认真看了下html2canvas的各个参数,发现可

    2024年02月03日
    浏览(59)
  • React--》学习Lodash:让你的JS代码更加优雅和易于阅读

            此时隔壁 vue专栏 正在项目实战,为了不打断它的文章连续性,我们把lodash的讲解文章搬到react专栏来进行学习,当然是否用框架或用什么框架都不会影响我们学习的恒心! 目录 初识Lodash 操作数组方法 操作语言方法 操作数学方法 操作对象方法 操作字符串方法

    2024年02月12日
    浏览(37)
  • react+vue 前端国密算法sm2、sm3 、sm4的js ts实现

    1. 简单介绍下SM2 和 SM3 SM2 算法:是一种公钥加密算法,它的密钥长度为 256 位,安全性较高。可用于数字签名、密钥协商等场景。 SM3 算法:是一种对称加密算法,用于消息摘要和数字签名等场景。它的密钥长度为 256 位,安全性较高。SM3 算法与 SM2 算法相互配合,提高了整体

    2024年01月19日
    浏览(41)
  • 简介:在这篇教程中,我们将使用React.js框架创建一个简单的聊天机器人的前端界面,并利用Dialogflo

    作者:禅与计算机程序设计艺术 介绍及动机 聊天机器人(Chatbot)一直是互联网领域中的热门话题。而很多聊天机器人的功能都依赖于人工智能(AI)技术。越来越多的企业希望拥有自己的聊天机器人系统,从而提升自己的竞争力。为此,业界也出现了很多基于开源技术或云

    2024年02月06日
    浏览(60)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包