React基础知识点

REACT

1 定义一个组件

export default function Profile() {
  return (
    <img
      src="https://i.imgur.com/MK3eW3Am.jpg"
      alt="Katherine Johnson"
    />
  )
}

一个组件必须是大写字母开头,不然不会生效

第一步:导出组件

export defaultjs语法,意思是默认导出,一个组件里面只能有一个默认导出。这样允许你能够在另外一个组件引用它。

第二步:定义函数

function Profile(){}

第三步:添加标签

这个组件允许返回img标签,看似是html,但实际上是js,这种语法被称为jsx

返回语句可以写在一行上

return<img src="https://i.imgur.com/MK3eW3Am.jpg" alt="Katherine Johnson"/>

也可以像上面的例子一样用()

注意:组件不能嵌套定义而且应该在顶层声明组件

总结:

  • React 是常规的 JavaScript 函数,除了:
    1. 它们的名字总是以大写字母开头。
    2. 它们返回 JSX 标签。

2 组件的导入与导出

  1. 创建一个新的JS文件来存放该组件
  2. 导出该组件的函数组件(可以使用默认导出或具名导出)
  3. 在需要使用该组件的文件导入

2.1 默认导入和导出

export - JavaScript | MDN (mozilla.org)

默认导入和具名导出是js原本的语法,一个页面可以有多个具名导出。

例:

// 导出单个特性
export let name1 =1
export function FunctionName(){}
export class ClassName{}

但是只能有一个默认导出,不然会报错。

2.2 默认导入和具名导入

在这里插入图片描述

也就是说,当这个组件使用默认导出的时候,如果你想在其他地方引用这个组件,导入名可以不跟导出名一致。而具名导入则相反

要求导入和导出的名字必须相同。

3 JSX

react使用jsx语法来返回html标签,这是因为由于渲染逻辑和标签是紧密相关的,所以 React 将它们存放在一个组件中。jsxjs的扩展,JSX 看起来和 HTML 很像,但它的语法更加严格并且可以动态展示信息。

jsx语法要求一个只能返回一个根组件,所以当你想要返回多个标签的时候,需要有一个父标签来包裹这些标签,可以是<div></div>或者是< >< / >(这个空标签被称作 Fragment。React Fragment 允许你将子元素分组,而不会在 HTML 结构中添加额外节点。)。

那么为什么需要用一个父标签来进行包裹呢,因为在JSX底层,代码都被转换为JS对象,你不能在一个函数中返回多个对象,但是可以把多个对象放在一个数组里面,然后返回一个数组,这就是为什么JSX需要父元素或者 *Fragment*进行包裹。

3.1 使用JSX编写JS逻辑和引用动态属性

1.使用引号传递字符串

可以使用''""来把一个字符串属性传递给JSX,如果需要动态的指定则需要用{}

2.可以在哪使用大括号

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

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

3.使用双大括号代表包裹了一个对象

例:

<ul style={
  {
    backgroundColor: 'black',
    color: 'pink'
  }
}>

请注意内联 style 属性 使用驼峰命名法编写。对象中的属性可以通过.来获取。

JSX 元素不是“实例”,因为它们没有内部状态也不是真实的 DOM 节点。

4 将 Props 传递给组件

此时是未进行传参的原代码

function Avatar() {
  return (
    <img
      className="avatar"
      src="https://i.imgur.com/1bX5QH6.jpg"
      alt="Lin Lanying"
      width={100}
      height={100}
    />
  );
}

export default function Profile() {
  return (
    <Avatar />
  );
}

步骤 1: 将 props 传递给子组件

首先,将一些 props 传递给 Avatar。例如,让我们传递两个 props:person(一个对象)和 size(一个数字):

export default function Profile() {

  return (
    <Avatar
      person={{ name: 'Lin Lanying', imageId: '1bX5QH6' }}
      size={100}
    />
  );
}

步骤 2: 在子组件中读取 props

你可以通过在 function Avatar 之后直接列出它们的名字 person, size 来读取这些 props。这些 props 在 ({}) 之间,并由逗号分隔。

function Avatar({ person, size }) {
  return (
    <img
      className="avatar"
      src={getImageUrl(person)}
      alt={person.name}
      width={size}
      height={size}
    />
  );
}

请注意虽然Props不是静态的,但是它也是不可变二点,这意味着子组件不能更改父组件传过来的Props,只能请求父组件传递不同的props,但是如果需要响应用户的选择时,可以设置state来进行改变。

5 条件渲染

在 React 中,你可以通过使用 JavaScriptif语句、&& ? :运算符来选择性地渲染 JSX

如果 isPacked 属性是 true,这段代码会返回一个不一样的 JSX。通过这样的改动,一些物品的名字后面会出现一个勾选符号:

例:

function Item({ name, isPacked }) {
  if (isPacked) {
    return <li className="item">{name}</li>;
  }
  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>
  );
}

还可以使用三目运算符

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

JavaScript && 表达式 :意思是

左侧(我们的条件)为 true 时,它则返回其右侧的值(在我们的例子里是勾选符号)。但条件的结果是 false,则整个表达式会变成 false

  • 在 JSX 中,{cond ? <A /> : <B />} 表示 “当 cond 为真值时, 渲染 <A />,否则 <B />
  • 在 JSX 中,{cond && <A />} 表示 “当 cond 为真值时, 渲染 <A />,否则不进行渲染”

6 渲染列表

JavaScript 的 filter() 方法会让数组的子项经过 “过滤器”(一个返回值为 truefalse 的函数)的筛选,最终返回一个只包含满足条件的项的新数组。

const chemists = people.filter(person =>
  person.profession === '化学家'
);

这段代码是在people里进行筛选,选出职业为化学家的人,并返回一个只包含化学家的新数组。

注意

箭头函数会隐式地返回位于 => 之后的表达式,所以你可以省略 return 语句。

const listItems = chemists.map(person =>
  <li>...</li> // 隐式地返回!
);

不过,如果你的 => 后面跟了一对花括号 { ,那你必须使用 return 来指定返回值!

const listItems = chemists.map(person => { // 花括号
  return <li>...</li>;
});

箭头函数 => { 后面的部分被称为 “块函数体”,块函数体支持多行代码的写法,但要用 return 语句才能指定返回值。假如你忘了写 return,那这个函数什么都不会返回!

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

这些 key 会告诉 React,每个组件对应着数组里的哪一项,所以 React 可以把它们匹配起来。这在数组项进行移动(例如排序)、插入或删除等操作时非常重要。一个合适的 key 可以帮助 React 推断发生了什么,从而得以正确地更新 DOM 树。

如果你想在以上的示例中,在<li></li>标签里渲染多个节点,可以使用<Fragment> 写法

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 需要满足的条件

  • key 值在兄弟节点之间必须是唯一的。 不过不要求全局唯一,在不同的数组中可以使用相同的 key。
  • key 值不能改变,否则就失去了使用 key 的意义!所以千万不要在渲染时动态地生成 key。

在这里插入图片描述

可以做一些练习:https://react.docschina.org/learn/rendering-lists#challenges

7 保证组件的纯粹

一个纯粹的组件应该包含以下要求:

  • 只负责自己的任务,不会在函数调用前就更改已经存在的对象或者变量
  • 给定相同的输出,永远返回相同的JSX
  • 不依赖其他组件的渲染顺序

值得一提的是reactvue一样要求传入的props不能直接被改变,而是要求直接重新传入一个全新的props

在 React 中,你可以在渲染时读取三种输入:propsstatecontext。你应该始终将这些输入视为只读。

React中的纯函数代表仅执行计算操作,不做其他操作,拒绝任何副作用,能使得组件变得单纯。每个组件要求步依赖其他组件渲染,也不和其他组件进行协调,保证了组件的独立性。

副作用通常通过React的事件处理程序来处理,因为事件处理程序无需是纯函数,即使是在组件内部定义但不会在渲染期间运行。

切记不要改变预先存在的对象或者变量

如果组件预先改变了预先存在的变量,这种情况叫做mutation。不过如果你是在渲染时,改变变量,这是允许存在的。

export default function TeaGathering() {
  let cups = [];
  for (let i = 1; i <= 12; i++) {
    cups.push(<Cup key={i} guest={i} />);
  }
  return cups;
}

因为每次渲染时,你都是在 TeaGathering 函数内部创建的它们。TeaGathering 之外的代码并不会知道发生了什么。这就被称为 “局部 mutation”

请注意:当你想要更改数组的任意项时,必须先对其进行拷贝。pushpopreversesort 会改变原始数组,但 slicefiltermap 则会创建一个新数组。

7.1 为什么纯函数如此重要

  1. 纯函数针对相同的输出,永远返回相同的结果,因此一个组件就能满足多个用户的需求
  2. 可以为输入未更改的组件来跳过渲染,因为纯函数总还是返回相同的结果,可以安全的缓存已经计算的结果

可以做一些练习:https://react.docschina.org/learn/rendering-lists#challenges

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值