Teknologian jakaminen

Reagoi perusoppimiseen - Day01

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Reagoi perusoppimiseen - Day01

1. Reactin esittely

1.1 Mitä on reagoida?

React on Facebookin kehittämä ja ylläpitämä avoimen lähdekoodin JavaScript-kirjasto käyttöliittymien rakentamiseen. Siitä lähtien, kun React tuli avoimeen lähdekoodiin vuonna 2013, siitä on tullut suosittu valinta etupään kehittämiseen, ja sitä käytetään laajasti yksisivuisten sovellusten (SPA) ja monimutkaisten monisivuisten sovellusten kehittämisessä. Reactin päätavoitteena on yksinkertaistaa käyttöliittymäkehitystä ja tehdä siitä tehokkaampi, joustavampi ja ylläpidettävämpi.

1.2 Mitkä ovat reactin edut?

1.2.1 Reactin edut DOM:iin verrattuna
  1. Virtuaalinen DOM ja tehokkaat päivitykset
    • Virtuaalinen DOM : React käyttää virtuaalista DOM:ia muistissa olevana kopiona edustamaan käyttöliittymärakenteita. Aina kun tiedot päivitetään, React suorittaa ensin laskelmia ja vertailuja virtuaalisessa DOM:ssa ja päivittää sitten muuttuneet osat todelliseksi DOM:ksi erissä. Tämä optimointi voi vähentää merkittävästi DOM-toimintoja ja parantaa suorituskykyä.
    • Vähennä uudelleenpiirroksia ja uudelleenjuoksuja: Virtuaalisen DOM:n avulla React voi välttää todellisen DOM:n toistuvan suoran manipuloinnin, vähentää sivun uudelleenmaalausta (uudelleenmaalausta) ja uudelleenjuoksua (reflow), mikä parantaa sivun vastausnopeutta ja suorituskykyä.
  2. Komponentointi ja uudelleenkäytettävyys
    • Komponentointi : React rohkaisee jakamaan käyttöliittymän itsenäisiksi komponenteiksi, jolloin jokainen komponentti vastaa omasta käyttöliittymästään ja logiikastaan. Tämän modulaarisen rakenteen ansiosta kehittäjien on helpompi käyttää, testata ja ylläpitää koodia.
    • Mukautettu komponentti : Kehittäjät voivat luoda mukautettuja komponentteja ja rakentaa monimutkaisia ​​käyttöliittymiä yhdistämällä näitä komponentteja. Tällaista joustavuutta ja uudelleenkäytettävyyttä ei ole saatavilla perinteisissä DOM-toiminnoissa.
  3. deklaratiivinen ohjelmointityyli
    • deklaratiivinen : Reactin ohjelmointityyli on ilmoittava Kehittäjien tarvitsee vain kuvata, miltä käyttöliittymän tulee näyttää, eikä heidän tarvitse huolehtia DOM:n käytöstä päivityksiä varten. Tämä lähestymistapa on intuitiivisempi ja helpompi ymmärtää, mikä parantaa koodin ylläpidettävyyttä.
    • tieto-ohjautuva: React korostaa käyttöliittymämuutosten ajamista tilan ja ominaisuuksien (rekvisiitta) kautta.
  4. Monialustaiset ominaisuudet
    • React Native : Verkkosovellusten lisäksi React tukee myös natiivimobiilisovellusten rakentamista käyttämällä samaa komponenttimallia. React Native tarjoaa tavan rakentaa tehokkaita alkuperäisiä käyttöliittymiä iOS- ja Android-käyttöjärjestelmiin, jolloin kehittäjät voivat jakaa suurimman osan koodistaan ​​ja taitostaan, mikä vähentää kehityskustannuksia ja oppimiskäyriä.
  5. Yhteisön ja ekosysteemin tuki
    • valtava yhteisö: Reactilla on aktiivinen ja laaja yhteisö, joka tarjoaa runsaasti kolmannen osapuolen kirjastoja, työkaluja ja ratkaisuja auttaakseen kehittäjiä kehittämään ja ottamaan sovelluksia tehokkaammin käyttöön.
    • Komponenttikirjasto: On olemassa monia erinomaisia ​​käyttöliittymäkomponenttikirjastoja (kuten Material-UI, Ant Design jne.) ja tilanhallintatyökaluja (kuten Redux, MobX jne.), joita voidaan käyttää yhdessä Reactin kanssa kehitystehokkuuden ja sovellusten parantamiseksi edelleen. esitys.

Yhteenvetona voidaan todeta, että verrattuna perinteisiin DOM-toimintoihin React tarjoaa tehokkaamman, ylläpidettävämmän ja skaalautuvamman kehitysmenetelmän ominaisuuksien, kuten virtuaalisen DOM:n, komponentoinnin ja deklaratiivisen ohjelmoinnin, avulla. Nämä edut tekevät Reactista yhden valtavirran viitekehyksestä etupään kehityksessä, ja sitä käytetään laajasti kaikenkokoisissa ja -tyyppisissä projekteissa.

1.2.2 Reactin ja muiden kehysten vertailu
  1. Joustavuus ja muokattavuus
    • Reagoi : React on pikemminkin kirjasto kuin täydellinen kehys. Se keskittyy enemmän tarjoamaan keskeisiä työkaluja ja mekanismeja käyttöliittymien rakentamiseen. Kehittäjät voivat vapaasti käyttää muita kirjastoja ja työkaluja (esim. se. Tämä joustavuus antaa kehittäjille mahdollisuuden räätälöidä ja optimoida tarkemmin projektin tarpeiden mukaan.
    • Vue.js: Vue.js tarjoaa kattavamman ratkaisun, joka sisältää reitityksen, tilanhallinnan ja koontityökalut Pienille ja keskikokoisille sovelluksille, Vue.js tarjoaa enemmän valmiita ominaisuuksia ja vähentää integroinnin ja konfiguroinnin monimutkaisuutta. .
  2. Virtuaalisen DOM:n käyttöönotto
    • Reagoi: React käyttää tehokkaita virtuaalisia DOM- ja diff-algoritmeja, mikä saa Reactin toimimaan hyvin suuria tietokokoelmia ja usein päivitettäessä.
    • Vue.js: Vue.js käyttää myös samanlaista virtuaalista DOM-tekniikkaa, mutta joissakin testeissä Reactin diff-algoritmi voi olla nopeampi, varsinkin kun käsitellään monimutkaisia ​​käyttöliittymäpäivityksiä.
  3. Ekosysteemin ja yhteisön tuki
    • Reagoi: Reactilla on laaja ja aktiivinen yhteisö, joka tukee runsaasti kolmannen osapuolen kirjastoja ja työkaluja, kuten Redux, Material-UI jne. Nämä kirjastot voivat auttaa kehittäjiä rakentamaan monimutkaisia ​​yksisivuisia sovelluksia ja suuria projekteja.
    • Vue.js: Vue.js-yhteisö on myös erittäin aktiivinen Vue.js-ekosysteemi tarjoaa monia laajennuksia ja työkaluja, kuten Vuex (tilanhallinta), Vue Router (reitityshallinta) jne., jotka tarjoavat kehittäjille enemmän valinnanvaraa ja integraatioratkaisuja. .
  4. Oppimiskäyrä ja helppokäyttöisyys
    • Reagoi : Reactin oppimiskäyrä on suhteellisen jyrkkä, varsinkin aloittelijoille, joiden täytyy hallita sellaisia ​​käsitteitä kuin JSX, komponenttien elinkaari ja tilanhallinta. Mutta kun hallitset Reactin ydinkonseptit, kehittäjät voivat rakentaa ja ylläpitää monimutkaisia ​​sovelluksia tehokkaammin.
    • Vue.js : Vue.js:n oppimiskäyrä on suhteellisen lempeä. Se on lähempänä perinteistä HTML:ää, CSS:ää ja JavaScriptiä ja on ystävällinen sekä kokeneille kehittäjille että aloittelijoille. Vue.js:n dokumentaatio ja opetusohjelmat ovat myös erittäin kattavia, mikä auttaa kehittäjiä pääsemään alkuun nopeasti.
  5. Yhteisökulttuuri ja reagointikyky
    • Reagoi : React-yhteisö kiinnittää enemmän huomiota suorituskykyyn ja joustavuuteen, ja on myös taipuvaisempia käyttämään tyyppiturvallisia teknologiapinoja, kuten TypeScriptiä. Reactin pääylläpitäjänä Facebookilla on korkeat takuut turvallisuudesta ja vakaudesta.
    • Vue.js : Vue.js-yhteisö on avoimempi ja ystävällisempi, ja se keskittyy kehittäjäkokemukseen ja helppokäyttöisyyteen. Vue.js on myös helpompi integroida muihin teknologiapinoihin, kuten integrointi olemassa oleviin projekteihin tai kirjastoihin.

Yleisesti ottaen React ja Vue.js ovat erinomaisia ​​etupään kehityskehyksiä. Sopivan kehyksen valinta riippuu projektin vaatimuksista, tiimin teknologiasta ja kehittäjien mieltymyksistä. React voi olla sopivampi suuriin ja monimutkaisiin sovelluksiin, erityisesti skenaarioihin, jotka vaativat suurta joustavuutta ja muokattavuutta, kun taas Vue.js sopii paremmin nopeaan kehitykseen sekä pieniin ja keskikokoisiin sovelluksiin, mikä tarjoaa integroidumpia ja kätevämpiä ratkaisuja.

1.2.3 Kuinka React vähentää uudelleenpiirtämistä ja uudelleenjärjestelyä DOM:iin verrattuna

Maalaa uudelleen ja sulata uudelleen

  1. Maalaa uudelleen: Kun elementin ulkoasutyyli (kuten väri, tausta, näkyvyys) muuttuu, mutta ei vaikuta asetteluun, uudelleenpiirustus käynnistyy.
  2. Reflow : Kun elementin koko, sijainti tai rakenne muuttuu, mikä vaikuttaa asetteluun, uudelleenjuoksu käynnistyy. Reflow on kalliimpaa kuin uudelleenpiirtäminen, koska asettelu ja renderöintipuu on laskettava uudelleen.

How React vähentää uudelleenpiirroksia ja uudelleenjuoksuja

  1. Virtual DOM (Virtual DOM)
    • Virtuaalinen DOM : React luo virtuaalisen DOM:n, joka on kevyt kopio käyttöliittymästä, joka säilytetään muistissa. Aina kun komponentin tila tai ominaisuudet muuttuvat, React suorittaa laskelmia ja vertailuja virtuaalisessa DOM:ssa luodakseen uuden virtuaalisen DOM-puun.
    • Diff-algoritmi: React käyttää tehokasta erotusalgoritmia vertaillakseen vanhoja ja uusia virtuaalisia DOM-puita, löytääkseen muuttuneet osat ja luodakseen päivityskorjauksen.
  2. Minimoi todellinen DOM-manipulaatio
    • Eräpäivitys : React yhdistää useita tilapäivityksiä yhdeksi eräpäivitykseksi vähentääkseen DOM-toimintojen määrää. Eräpäivitys välttää toistuvien DOM-toimintojen aiheuttaman suorituskyvyn menetyksen päivittämällä useita muutoksia kerralla.
    • Asynkroniset päivitykset: React käyttää asynkronista eräkäsittelyä (kuten React 18:ssa käyttöön otettua Concurrent Mode -tilaa) useiden tilapäivitysten yhdistämiseen toistuvien synkronisten DOM-toimintojen välttämiseksi.
  3. Vältä tarpeettomia päivityksiä
    • shouldComponentUpdate: Voidaan käyttää luokan komponenteissa shouldComponentUpdate Menetelmä, jolla ohjataan, tarvitseeko komponentti renderöidä uudelleen tarpeettomien uudelleenpiirtämisten ja uudelleenjuoksujen välttämiseksi.
    • React.memo: Toimintokomponentteja voidaan käyttää React.memo Suorituskyvyn optimointia varten se vertaa ominaisuuksia ennen ja jälkeen ja hahmontaa komponentin uudelleen vain, kun ominaisuudet muuttuvat.
    • useMemo jauseCallback: Tarjoaa Hooks useMemo jauseCallback Laskentatulokset ja funktioviitteet voidaan tallentaa välimuistiin alikomponenttien tarpeettomien päivitysten välttämiseksi.
  4. Yhdistä päivitykset
    • Erän tilapäivitykset: React yhdistää automaattisesti useita tilapäivityksiä ja laukaisee vain yhden renderöinnin yhdessä tapahtumasilmukassa, mikä vähentää DOM-toimintoja.

Esimerkkikoodi

Seuraava esimerkki osoittaa, kuinka React voi kulkea React.memo jauseMemo Tarpeettoman renderöinnin vähentäminen:

import React, { useState, useMemo } from 'react';

// 一个简单的子组件,仅在 props 变化时重新渲染
const ChildComponent = React.memo(({ value }) => {
  console.log('ChildComponent render');
  return <div>{value}</div>;
});

function App() {
  const [count, setCount] = useState(0);
  const [text, setText] = useState('');

  // 使用 useMemo 缓存计算结果,避免不必要的计算
  const memoizedValue = useMemo(() => {
    console.log('Calculating memoized value');
    return count * 2;
  }, [count]);

  return (
    <div>
      <h1>Count: {count}</h1>
      <button onClick={() => setCount(count + 1)}>Increment</button>
      <input 
        type="text" 
        value=
                    
                        
                    
                    

React基础学习-Day01

1.React介绍

1.1 react是什么?

React 是一个用于构建用户界面的开源 JavaScript 库,由 Facebook 开发和维护。自 2013 年开源以来,React 已成为前端开发的热门选择,广泛应用于单页应用(SPA)和复杂的多页应用的开发。React 的主要目标是简化 UI 开发,使其更加高效、灵活和可维护。

1.2 react的优势?

1.2.1 react对比DOM的优势体现
  1. 虚拟 DOM 和高效更新
    • 虚拟 DOM:React 使用虚拟 DOM 作为内存中的副本来表示 UI 结构。每次数据更新时,React 首先在虚拟 DOM 中进行计算和比较,然后再将变化的部分批量更新到实际 DOM 中。这种优化能够显著减少 DOM 操作,提升性能。
    • 减少重绘和回流:通过虚拟 DOM,React 可以避免频繁地直接操作实际 DOM,减少页面重绘(repaint)和回流(reflow),从而提高页面的响应速度和性能。
  2. 组件化和可复用性
    • 组件化:React 鼓励将 UI 拆分为独立的组件,每个组件负责自己的 UI 和逻辑。这种模块化的设计使得开发者可以更容易地复用、测试和维护代码。
    • 自定义组件:开发者可以创建自定义的组件,并通过组合这些组件来构建复杂的 UI。这种灵活性和可复用性是传统 DOM 操作所不具备的。
  3. 声明式编程风格
    • 声明式:React 的编程风格是声明式的,开发者只需描述 UI 应该是什么样子,而不需要关心如何操作 DOM 进行更新。这种方式更加直观和易于理解,提高了代码的可维护性。
    • 数据驱动:React 强调通过状态(state)和属性(props)来驱动 UI 的变化,数据变化时,React 负责更新 UI,开发者无需手动操作 DOM。
  4. 跨平台能力
    • React Native:除了 Web 应用外,React 还支持使用相同的组件模型构建原生移动应用。React Native 提供了一种在 iOS 和 Android 上构建高性能、原生用户界面的方式,这使得开发者可以共享大部分代码和技能,减少开发成本和学习曲线。
  5. 社区和生态系统支持
    • 庞大的社区:React 拥有一个活跃和庞大的社区,提供了丰富的第三方库、工具和解决方案,帮助开发者更高效地开发和部署应用。
    • 组件库:有许多优秀的 UI 组件库(如 Material-UI、Ant Design 等)和状态管理工具(如 Redux、MobX 等),可以与 React 配合使用,进一步提升开发效率和应用性能。

总结来说,React 相对于传统的 DOM 操作,通过虚拟 DOM、组件化、声明式编程等特性,提供了更高效、可维护和可扩展的开发方式。这些优势使得 React 成为前端开发中的主流框架之一,被广泛应用于各种规模和类型的项目中。

1.2.2 react与其他框架的对比
  1. 灵活性和可定制性
    • React:React 本身是一个库而非完整的框架,它更注重于提供构建用户界面的核心工具和机制,开发者可以自由选择配合使用其他库和工具(如 Redux、React Router 等)。这种灵活性使得开发者可以根据项目需求进行更精确的定制和优化。
    • Vue.js:Vue.js 提供了更全面的解决方案,包括路由、状态管理和构建工具等,对于小型到中型应用,Vue.js 提供了更多开箱即用的功能,减少了集成和配置的复杂性。
  2. 虚拟 DOM 的实现
    • React:React 使用了一套高效的虚拟 DOM 和 diff 算法,这使得 React 在处理大型数据集合和频繁数据更新时性能表现优越。
    • Vue.js:Vue.js 也使用了类似的虚拟 DOM 技术,但在一些测试中,React 的 diff 算法可能会更快一些,尤其是在处理复杂的 UI 更新时。
  3. 生态系统和社区支持
    • React:React 拥有一个庞大和活跃的社区,支持丰富的第三方库和工具,如 Redux、Material-UI 等,这些库能够帮助开发者构建复杂的单页应用和大型项目。
    • Vue.js:Vue.js 社区同样非常活跃,Vue.js 生态系统提供了许多插件和工具,如 Vuex(状态管理)、Vue Router(路由管理)等,为开发者提供了更多的选择和集成方案。
  4. 学习曲线和易用性
    • React:React 的学习曲线相对较陡,特别是对于初学者来说,需要掌握 JSX、组件生命周期、状态管理等概念。但一旦掌握了 React 的核心概念,开发者可以更高效地构建和维护复杂的应用。
    • Vue.js:Vue.js 的学习曲线相对平缓,它更接近传统的 HTML、CSS 和 JavaScript,对于有经验的开发者和新手来说都较为友好。Vue.js 的文档和教程也很全面,帮助开发者快速入门和上手。
  5. 社区文化和响应性
    • React:React 社区倾向于更加注重性能和灵活性,也更倾向于使用 TypeScript 等类型安全的技术栈。Facebook 作为 React 的主要维护者,对于安全性和稳定性有较高的保障。
    • Vue.js:Vue.js 社区更加开放和友好,注重开发者体验和易用性。Vue.js 也更容易与其他技术栈集成,比如可以很方便地与现有的项目或库整合。

总体来说,React 和 Vue.js 都是优秀的前端开发框架,选择适合的框架取决于项目需求、团队技术栈和开发者的偏好。React 在大型和复杂的应用中可能更适合,特别是需要高度灵活性和可定制性的场景;而 Vue.js 则更适合于快速开发和中小型应用,提供了更多集成和便捷的解决方案。

1.2.3 react对比DOM如何减少重绘和重排

重绘 (Repaint) 和回流 (Reflow)

  1. 重绘 (Repaint):当元素的外观样式(如颜色、背景、可见性)发生变化,但不影响布局时,会触发重绘。
  2. 回流 (Reflow):当元素的尺寸、位置或结构发生变化,影响布局时,会触发回流。回流比重绘更耗费性能,因为需要重新计算布局和渲染树。

React 如何减少重绘和回流

  1. 虚拟 DOM (Virtual DOM)
    • 虚拟 DOM:React 创建了一个虚拟 DOM,它是 UI 的轻量级副本,保存在内存中。每次组件的状态或属性发生变化时,React 会在虚拟 DOM 中进行计算和比较,生成新的虚拟 DOM 树。
    • Diff 算法:React 使用高效的 diff 算法比较新旧虚拟 DOM 树,找出变化的部分,并生成一个更新补丁。
  2. 最小化实际 DOM 操作
    • 批量更新:React 将多个状态更新合并为一次批量更新,减少 DOM 操作次数。批量更新通过一次性更新多个变化,避免频繁操作 DOM 导致的性能损耗。
    • 异步更新:React 通过异步批处理(例如 React 18 中引入的 Concurrent Mode),将多次状态更新合并处理,避免频繁的同步 DOM 操作。
  3. 避免不必要的更新
    • shouldComponentUpdate:类组件中可以使用 shouldComponentUpdate 方法来控制组件是否需要重新渲染,从而避免不必要的重绘和回流。
    • React.memo:函数组件可以使用 React.memo 进行性能优化,它会对比前后属性,只有属性变化时才会重新渲染组件。
    • useMemouseCallback:Hooks 提供的 useMemouseCallback 可以缓存计算结果和函数引用,避免子组件不必要的更新。
  4. 合并更新
    • 批量状态更新:React 会自动合并多次状态更新,在一次事件循环内只触发一次渲染,从而减少 DOM 操作。

示例代码

以下示例演示了 React 如何通过 React.memouseMemo 来减少不必要的渲染:

import React, { useState, useMemo } from 'react';

// 一个简单的子组件,仅在 props 变化时重新渲染
const ChildComponent = React.memo(({ value }) => {
  console.log('ChildComponent render');
  return <div>{value}</div>;
});

function App() {
  const [count, setCount] = useState(0);
  const [text, setText] = useState('');

  // 使用 useMemo 缓存计算结果,避免不必要的计算
  const memoizedValue = useMemo(() => {
    console.log('Calculating memoized value');
    return count * 2;
  }, [count]);

  return (
    <div>
      <h1>Count: {count}</h1>
      <button onClick={() => setCount(count + 1)}>Increment</button>
      <input 
        type="text" 
        value={text} 
        onChange={(e) => setText(e.target.value)} 
      />
      <ChildComponent value={memoizedValue} />
    </div>
  );
}

export default App;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

在这个示例中:

  • ChildComponent 只有在 value 变化时才会重新渲染,因为它被 React.memo 包裹。
  • memoizedValue 使用 useMemo 进行缓存,只有在 count 变化时才会重新计算,避免了不必要的计算和渲染。

总结

通过虚拟 DOM、批量更新、避免不必要的更新和合并更新,React 有效地减少了重绘和回流的次数,从而提升了应用的性能。与传统的直接操作 DOM 的方式相比,React 提供了一种更加高效和优化的 UI 更新机制。

2.jsx语法介绍

.jsxJavaScript XML 的缩写,它是一种 JavaScript 的语法扩展,允许开发者在 JavaScript 中直接编写类似 HTML 的标记语言,用于定义 React 组件的 UI 结构。以下是一些 .jsx 语法的核心特点和使用方法:

主要特点:

  1. 类 HTML 结构
    • .jsx 允许在 JavaScript 中嵌入类似 HTML 的标记语言,用于声明 UI 的结构和组件的外观。
    • 例如,在 React 中,可以直接使用 <div><span><h1> 等 HTML 标签,以及自定义的 React 组件。
  2. JSX 表达式
    • .jsx 中,可以使用 {} 花括号来包裹 JavaScript 表达式,用于在标记中动态地插入变量、计算结果或函数调用。
    • 这使得 .jsx 具有了 JavaScript 的全部表达能力,可以进行条件判断、循环、计算等操作。
  3. 属性传递
    • 类似 HTML,.jsx 允许在标签上使用属性,并支持使用表达式作为属性值。
    • 例如:<Component name={variable} />,其中 name 是一个属性,variable 是一个 JavaScript 变量或表达式。
  4. 自闭合标签
    • .jsx 中的标签可以是自闭合的,比如 <img><input>,也可以使用 / 符号来表示自闭合,例如 <br />
  5. 注释
    • 和 JavaScript 一样,可以使用 // 单行注释和 /* */ 多行注释在 .jsx 文件中添加注释(注释要写在{}内)。

示例:

以下是一个简单的 React 组件示例,展示了 .jsx 的基本语法和特点:

import React from 'react';

// 定义一个 React 函数组件
const MyComponent = () => {
  const name = 'World';

  return (
    <div>
      <h1>Hello, {name}!</h1>
      <p>Welcome to JSX!</p>
      <ul>
        {['apple', 'banana', 'cherry'].map((fruit, index) => (
          <li key={index}>{fruit}</li>
        ))}
      </ul>
    </div>
  );
};

export default MyComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

在这个例子中:

  • <h1><p><ul><li> 等标签直接在 JavaScript 函数中使用,用于构建组件的 UI 结构。
  • 使用 {name}<h1> 中动态地插入变量 name 的值。
  • 使用 {} 花括号包裹的 JavaScript 表达式,例如 ['apple', 'banana', 'cherry'].map() 来生成列表项 <li>
  • key={index} 用于在 React 中标识列表项的唯一性,帮助 React 更高效地管理组件的更新。

注意事项:

  • JSX 本质上是 JavaScript 语法的扩展,需要通过 Babel 等工具进行编译转换成标准的 JavaScript 代码,以便浏览器能够正确解析和执行。
  • JSX 让开发者可以更直观地编写和理解 React 组件的结构和逻辑,提高了代码的可读性和开发效率。

总结来说,.jsx 是 React 中用于定义组件 UI 结构的一种语法扩展,它结合了 JavaScript 的表达能力和 HTML 标记的直观性,是开发现代 Web 应用的重要工具之一。

3.jsx实现列表渲染

import React from 'react';

const MyComponent = () => {
  // 假设我们有一个水果列表
  const fruits = ['apple', 'banana', 'cherry'];

  return (
    <div>
      <h2>Fruit List:</h2>
      <ul>
        {/* 使用 map 方法遍历数组,并为每个元素生成一个 <li> 元素 */}
        {fruits.map((fruit, index) => (
          <li key={index}>{fruit}</li>
        ))}
      </ul>
    </div>
  );
};

export default MyComponent;

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

4.jsx实现条件渲染

4.1 三元运算符 (Ternary Operator)

这是最常用的方式,通过三元运算符来实现简单的条件渲染。

import React from 'react';

const MyComponent = () => {
  const isLoggedIn = true;

  return (
    <div>
      {isLoggedIn ? <p>Welcome back!</p> : <p>Please sign in.</p>}
    </div>
  );
};

export default MyComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

4.2. 逻辑与运算符 (Logical AND Operator)

适用于条件为真时才渲染内容的场景。

import React from 'react';

const MyComponent = () => {
  const isLoggedIn = true;

  return (
    <div>
      {isLoggedIn && <p>Welcome back!</p>}
    </div>
  );
};

export default MyComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

4.3. 立即执行函数表达式 (IIFE)

适用于需要执行更多逻辑或多条件判断的情况。

import React from 'react';

const MyComponent = () => {
  const status = 'loggedOut'; // 可以是 'loggedIn' 或 'loggedOut'

  return (
    <div>
      {(() => {
        if (status === 'loggedIn') {
          return <p>Welcome back!</p>;
        } else if (status === 'loggedOut') {
          return <p>Please sign in.</p>;
        } else {
          return <p>Status unknown.</p>;
        }
      })()}
    </div>
  );
};

export default MyComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

4.4 条件渲染组件

将条件渲染逻辑封装到单独的组件中,可以提高代码的可读性和复用性。

import React from 'react';

const Greeting = ({ isLoggedIn }) => {
  if (isLoggedIn) {
    return <p>Welcome back!</p>;
  } else {
    return <p>Please sign in.</p>;
  }
};

const MyComponent = () => {
  const isLoggedIn = true;

  return (
    <div>
      <Greeting isLoggedIn={isLoggedIn} />
    </div>
  );
};

export default MyComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

5.React基础事件绑定

5.1 基本事件绑定

在 React 中,可以直接在 JSX 中通过类似 HTML 的方式来绑定事件处理函数。例如,给按钮绑定点击事件:

import React from 'react';

const MyComponent = () => {
  const handleClick = () => {
    console.log('Button clicked!');
  };

  return (
    <div>
      <button onClick={handleClick}>Click me</button>
    </div>
  );
};

export default MyComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

在这个例子中,onClick 是 React 的事件属性,它接收一个函数作为值。当按钮被点击时,handleClick 函数会被调用。

5.2 事件处理函数

React 的事件处理函数与普通的 JavaScript 事件处理函数类似,它们接收一个合成事件对象 (SyntheticEvent),而不是原生 DOM 事件对象。这使得跨浏览器的事件处理更加一致和可靠。

import React from 'react';

const MyComponent = () => {
  const handleClick = (event) => {
    console.log('Button clicked!', event.target);
  };

  return (
    <div>
      <button onClick={handleClick}>Click me</button>
    </div>
  );
};

export default MyComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

在上面的示例中,handleClick 函数的参数 event 是一个合成事件对象,可以通过 event.target 访问触发事件的 DOM 元素。

5.3 事件传参

有时候需要给事件处理函数传递额外的参数。可以使用箭头函数或者 bind 方法来实现这一点。

使用箭头函数:

import React from 'react';

const MyComponent = () => {
  const handleClick = (name) => {
    console.log(`Hello, ${name} clicked!`);
  };

  return (
    <div>
      <button onClick={() => handleClick('World')}>Click me</button>
    </div>
  );
};

export default MyComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

使用 bind 方法:

import React from 'react';

const MyComponent = () => {
  const handleClick = (name) => {
    console.log(`Hello, ${name} clicked!`);
  };

  return (
    <div>
      <button onClick={handleClick.bind(null, 'World')}>Click me</button>
    </div>
  );
};

export default MyComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

这两种方式都可以将 'World' 作为参数传递给 handleClick 函数。

5.4 阻止事件默认行为和冒泡

在 React 中,阻止事件的默认行为和冒泡可以通过合成事件对象的方法来实现。

阻止默认行为:

import React from 'react';

const MyComponent = () => {
  const handleClick = (event) => {
    event.preventDefault();
    console.log('Button clicked!');
  };

  return (
    <div>
      <a href="#" onClick={handleClick}>Click me</a>
    </div>
  );
};

export default MyComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

阻止冒泡:

import React from 'react';

const MyComponent = () => {
  const handleClick = (event) => {
    event.stopPropagation();
    console.log('Button clicked!');
  };

  return (
    <div onClick={() => console.log('Div clicked!')}>
      <button onClick={handleClick}>Click me</button>
    </div>
  );
};

export default MyComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

总结

React 的事件绑定和处理与传统的 JavaScript 事件处理有些许差异,主要体现在事件对象的处理上,使用合成事件对象来实现跨浏览器一致性。通过上述方法,可以有效地在 React 中处理各种事件,并进行事件传参、阻止默认行为和冒泡等操作。

6.组件是什么?

在 React 中,组件是构建用户界面的基本单位,可以将 UI 分割成独立的、可复用的代码片段。组件可以是函数组件或类组件,它们可以接收输入的数据(称为 props)并返回描述页面展示内容的 React 元素。组件可以包含其他组件、HTML 标签和逻辑,使得复杂的 UI 可以被有效地管理和开发。

主要特点和作用:

  1. 封装和复用
    • 组件可以将 UI 划分成独立的部分,每个部分负责自己的功能,从而提高代码的可维护性和复用性。
  2. 组件层级
    • 组件可以嵌套组合,形成层次化的结构。父组件可以向子组件传递数据和函数,实现数据的流动和交互的功能。
  3. 状态管理
    • 类组件可以拥有状态(state),用于存储和管理组件内部的数据。状态的改变会触发组件的重新渲染,从而更新用户界面。
  4. 生命周期
    • 类组件具有生命周期方法,例如 componentDidMountcomponentDidUpdatecomponentWillUnmount 等,用于在组件生命周期不同阶段执行特定的逻辑。
  5. 纯UI组件和容器组件
    • 纯UI组件(Presentational Components)负责如何渲染数据,不涉及业务逻辑。容器组件(Container Components)则负责管理数据和状态,传递给纯UI组件。

示例:

以下是一个简单的 React 函数组件的示例,展示了一个名为 HelloWorld 的组件,它接收一个 name 属性作为输入,并渲染一个简单的问候语句:

import React from 'react';

// 函数组件:HelloWorld
const HelloWorld = ({ name }) => {
  return (
    <div>
      <h1>Hello, {name}!</h1>
      <p>Welcome to React components.</p>
    </div>
  );
};

export default HelloWorld;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

在这个例子中,HelloWorld 组件接收一个 name 属性,用于动态显示问候语。这种组件可以被多次使用,每次使用时传入不同的 name 属性,使得界面呈现的问候语可以个性化定制。

总之,React 组件是构建现代 Web 应用的核心概念之一,它们通过组合和抽象,使得开发者可以更加高效和灵活地构建用户界面。

7.useState使用介绍

useState 是 React 中的一个 Hook,用于在函数组件中添加状态管理功能。它允许你在函数组件中声明状态变量,并提供一个方法来更新这些状态。

使用方法

useState 是从 React 中导入的,并且通常在函数组件的顶部进行调用。它返回一个包含两个元素的数组:当前状态值和一个更新状态的函数。

基本示例

import React, { useState } from 'react';

const Counter = () => {
  // 声明一个名为 "count" 的状态变量,初始值为 0
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
};

export default Counter;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

在这个示例中:

  • const [count, setCount] = useState(0); 声明了一个名为 count 的状态变量,初始值为 0useState 返回一个数组,第一个元素是当前状态值(count),第二个元素是更新状态的函数(setCount)。
  • 每次点击按钮时,调用 setCount(count + 1) 更新 count 的值,从而触发组件的重新渲染,并更新显示的点击次数。

使用多个状态变量

你可以在一个组件中使用多个 useState 调用来管理不同的状态变量:

import React, { useState } from 'react';

const MultiStateComponent = () => {
  const [count, setCount] = useState(0);
  const [text, setText] = useState('');

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
      <input
        type="text"
        value={text}
        onChange={(e) => setText(e.target.value)}
        placeholder="Type something..."
      />
      <p>You typed: {text}</p>
    </div>
  );
};

export default MultiStateComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

在这个示例中,我们使用了两个 useState 调用来分别管理 counttext 两个状态变量。

初始化状态

你可以将状态的初始值设置为函数返回的值,这在初始化需要执行复杂计算时特别有用:

import React, { useState } from 'react';

const ExpensiveComponent = () => {
  const initialCount = () => {
    // 模拟一个复杂的计算
    return 42;
  };

  const [count, setCount] = useState(initialCount);

  return (
    <div>
      <p>Initial count: {count}</p>
      <button onClick={() => setCount(count + 1)}>
        Increment
      </button>
    </div>
  );
};

export default ExpensiveComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

在这个示例中,initialCount 函数只会在组件初次渲染时执行一次,用于计算初始状态值。

总结

  • useState 是一个 React Hook,用于在函数组件中添加状态管理功能。
  • useState 返回一个包含当前状态值和一个更新状态的函数的数组。
  • 可以使用多个 useState 调用来管理多个状态变量。
  • 状态的初始值可以是一个复杂计算的结果,通过传递一个函数来实现。

8.修改状态的规则

在 React 中,使用 useState 来管理和修改状态时,有一些规则和最佳实践需要遵循,以确保状态的管理和更新过程是高效和可靠的。以下是修改状态的主要规则和一些示例:

1. 状态更新是异步的

React 的状态更新是异步的,这意味着调用状态更新函数后,状态的更新不会立即反映出来,而是在下一次重新渲染时才会生效。

import React, { useState } from 'react';

const Counter = () => {
  const [count, setCount] = useState(0);

  const handleClick = () => {
    setCount(count + 1);
    console.log(count); // 这里的 count 可能不会立即更新
  };

  return (
    <div>
      <p>{count}</p>
      <button onClick={handleClick}>Increment</button>
    </div>
  );
};

export default Counter;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

在上述例子中,console.log(count) 可能不会立即显示更新后的值,因为状态更新是异步的。

2. 状态更新函数接受当前状态作为参数

为了确保状态更新时使用的值是最新的,可以传递一个函数给状态更新函数。这个函数会接收当前的状态值作为参数。

import React, { useState } from 'react';

const Counter = () => {
  const [count, setCount] = useState(0);

  const handleClick = () => {
    setCount(prevCount => prevCount + 1);
  };

  return (
    <div>
      <p>{count}</p>
      <button onClick={handleClick}>Increment</button>
    </div>
  );
};

export default Counter;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

在这个示例中,setCount 接收一个函数 prevCount => prevCount + 1,确保使用的是最新的状态值进行更新。

3. 不要直接修改状态

状态应该是不可变的,不要直接修改状态对象,而是通过创建新对象来更新状态。

import React, { useState } from 'react';

const Example = () => {
  const [user, setUser] = useState({ name: 'John', age: 30 });

  const updateAge = () => {
    setUser(prevUser => ({
      ...prevUser,
      age: prevUser.age + 1
    }));
  };

  return (
    <div>
      <p>{user.name}</p>
      <p>{user.age}</p>
      <button onClick={updateAge}>Increment Age</button>
    </div>
  );
};

export default Example;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

在这个示例中,使用扩展运算符 ...prevUser 创建了一个新的用户对象,并更新了年龄属性。

4. 合并状态

对于对象类型的状态,需要手动合并更新的部分,因为 useState 不会自动合并更新对象。

import React, { useState } from 'react';

const Example = () => {
  const [user, setUser] = useState({ name: 'John', age: 30 });

  const updateName = () => {
    setUser(prevUser => ({
      ...prevUser,
      name: 'Doe'
    }));
  };

  return (
    <div>
      <p>{user.name}</p>
      <p>{user.age}</p>
      <button onClick={updateName}>Update Name</button>
    </div>
  );
};

export default Example;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

在这个示例中,setUser 的更新函数创建了一个新的用户对象,同时保持其他属性不变。

5. 避免不必要的状态更新

尽量避免在每次渲染中都调用状态更新函数,只有在需要时才更新状态,以提高性能。

import React, { useState } from 'react';

const Example = () => {
  const [count, setCount] = useState(0);

  const handleClick = () => {
    if (count < 10) {
      setCount(count + 1);
    }
  };

  return (
    <div>
      <p>{count}</p>
      <button onClick={handleClick}>Increment</button>
    </div>
  );
};

export default Example;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

在这个示例中,只有在 count 小于 10 时才会更新状态,避免了不必要的状态更新。

总结

  1. 状态更新是异步的:不能依赖立即更新后的值。
  2. 使用函数式更新:在更新状态时,传递一个函数来确保使用最新的状态值。
  3. 不要直接修改状态:状态应该是不可变的,需要通过创建新对象来更新状态。
  4. 手动合并状态:对于对象类型的状态,需要手动合并更新部分。
  5. 避免不必要的状态更新:只有在需要时才更新状态,以提高性能。

9.基础样式方案

1.行内样式(不推荐):<div style={{color:“red”}}></>

2.class类名控制:

10.classNames优化类名控制

<div className={classNames(“foo”,{active:true})}>

onChange={(e) => setText(e.target.value)} /> <ChildComponent value={memoizedValue} /> </div> ); } export default App;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

Tässä esimerkissä:

  • ChildComponent vain klovalue Se hahmonnetaan uudelleen vain, kun se muuttuu, koska se onReact.memo pakkaus.
  • memoizedValue käyttääuseMemo Välimuisti, vain joscount Se lasketaan uudelleen vain, kun se muuttuu, välttäen turhaa laskemista ja renderöintiä.

Tee yhteenveto

Virtuaalisen DOM:n, eräpäivitysten, tarpeettomien päivitysten välttämisen ja päivitysten yhdistämisen avulla React vähentää tehokkaasti uudelleenpiirtämisten ja uudelleenjärjestelyjen määrää, mikä parantaa sovelluksen suorituskykyä. Verrattuna perinteiseen tapaan käsitellä suoraan DOM:ia, React tarjoaa tehokkaamman ja optimoidun käyttöliittymän päivitysmekanismin.

2. Johdatus jsx-syntaksiin

.jsx JooJavaScript XML Lyhenne , se on JavaScriptin syntaksilaajennus, jonka avulla kehittäjät voivat kirjoittaa suoraan HTML:n kaltaista merkintäkieltä JavaScriptiin määrittääkseen React-komponenttien käyttöliittymärakenteen.Tässä on joitain.jsx Kieliopin ydinominaisuudet ja käyttö:

pääominaisuus:

  1. HTML-tyyppinen rakenne
    • .jsx Mahdollistaa HTML:n kaltaisen merkintäkielen upottamisen JavaScriptiin käyttöliittymän rakenteen ja komponenttien ulkonäön määrittämiseksi.
    • Esimerkiksi Reactissa voit käyttää suoraan <div><span><h1> HTML-tunnisteet ja mukautetut React-komponentit.
  2. JSX-lauseke
    • olla olemassa .jsx sisään, voidaan käyttää{} Kaarevia aaltosulkuja käytetään käärimään JavaScript-lausekkeet ja lisäämään dynaamisesti muuttujia, laskentatuloksia tai funktiokutsuja merkintöihin.
    • Tämä tekee .jsx Siinä on kaikki JavaScriptin ilmaisuominaisuudet ja se voi suorittaa toimintoja, kuten ehdollisen tuomion, silmukoiden ja laskelmien.
  3. Omaisuuden siirto
    • Samanlainen kuin HTML,.jsx Mahdollistaa attribuuttien käytön tarroissa ja tukee lausekkeita attribuuttiarvoina.
    • Esimerkiksi:<Component name={variable} />,sisään name on attribuutti,variable on JavaScript-muuttuja tai lauseke.
  4. itsestään sulkeutuva etiketti
    • .jsx Tarrat voivat olla itsestään sulkeutuvia, kuten<img><input>, voit myös käyttää / symboli edustamaan itsesulkeutumista, esim.<br />
  5. Kommentti
    • Kuten JavaScript, voit käyttää // yhden rivin kommentit ja/* */ Moniriviset kommentit sisään.jsx Lisää kommentteja tiedostoon (Kommentit tulee kirjoittaa sisällä {})。

Esimerkki:

Tässä on yksinkertainen React-komponenttiesimerkki .jsx Perussyntaksi ja ominaisuudet:

import React from 'react';

// 定义一个 React 函数组件
const MyComponent = () => {
  const name = 'World';

  return (
    <div>
      <h1>Hello, {name}!</h1>
      <p>Welcome to JSX!</p>
      <ul>
        {['apple', 'banana', 'cherry'].map((fruit, index) => (
          <li key={index}>{fruit}</li>
        ))}
      </ul>
    </div>
  );
};

export default MyComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

Tässä esimerkissä:

  • <h1><p><ul> ja<li> Tällaisia ​​tunnisteita käytetään suoraan JavaScript-funktioissa komponentin käyttöliittymärakenteen rakentamiseen.
  • käyttää {name} olla olemassa<h1> Lisää muuttujia dynaamisestiname arvo.
  • käyttää {} Esimerkiksi JavaScript-lausekkeet, jotka on kääritty aaltosulkeisiin['apple', 'banana', 'cherry'].map() luodaksesi luettelokohteita<li>
  • key={index} Käytetään yksilöimään luettelokohteet Reactissa, mikä auttaa Reactia hallitsemaan komponenttipäivityksiä tehokkaammin.

Varotoimenpiteet:

  • JSX on pohjimmiltaan JavaScript-syntaksin laajennus.Se on käännettävä ja muutettava tavalliseksi JavaScript-koodiksi työkaluilla, kuten Babel., jotta selain voi jäsentää ja suorittaa sen oikein.
  • JSX:n avulla kehittäjät voivat kirjoittaa ja ymmärtää React-komponenttien rakennetta ja logiikkaa intuitiivisemmin, mikä parantaa koodin luettavuutta ja kehitystehokkuutta.

Tiivistettynä,.jsx Se on syntaksilaajennus, jota käytetään Reactissa komponenttien käyttöliittymärakenteen määrittelemiseen. Siinä yhdistyvät JavaScriptin ilmaisuvoima ja HTML-tunnisteiden intuitiivisuus. Se on yksi tärkeimmistä työkaluista nykyaikaisten verkkosovellusten kehittämisessä.

3.jsx toteuttaa luettelon renderöinnin

import React from 'react';

const MyComponent = () => {
  // 假设我们有一个水果列表
  const fruits = ['apple', 'banana', 'cherry'];

  return (
    <div>
      <h2>Fruit List:</h2>
      <ul>
        {/* 使用 map 方法遍历数组,并为每个元素生成一个 <li> 元素 */}
        {fruits.map((fruit, index) => (
          <li key={index}>{fruit}</li>
        ))}
      </ul>
    </div>
  );
};

export default MyComponent;

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

4.jsx toteuttaa ehdollisen renderöinnin

4.1 Kolmiosainen operaattori

Tämä on yleisin tapa toteuttaa yksinkertainen ehdollinen renderöinti kolmiosaisen operaattorin avulla.

import React from 'react';

const MyComponent = () => {
  const isLoggedIn = true;

  return (
    <div>
      {isLoggedIn ? <p>Welcome back!</p> : <p>Please sign in.</p>}
    </div>
  );
};

export default MyComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

4.2 Looginen JA operaattori

Koskee skenaarioita, joissa sisältö hahmonnetaan vain, kun ehto on tosi.

import React from 'react';

const MyComponent = () => {
  const isLoggedIn = true;

  return (
    <div>
      {isLoggedIn && <p>Welcome back!</p>}
    </div>
  );
};

export default MyComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

4.3 Suorita välittömästi funktiolauseke (IIFE)

Sopii tilanteisiin, joissa tarvitaan enemmän logiikkaa tai usean ehdon arviointia.

import React from 'react';

const MyComponent = () => {
  const status = 'loggedOut'; // 可以是 'loggedIn' 或 'loggedOut'

  return (
    <div>
      {(() => {
        if (status === 'loggedIn') {
          return <p>Welcome back!</p>;
        } else if (status === 'loggedOut') {
          return <p>Please sign in.</p>;
        } else {
          return <p>Status unknown.</p>;
        }
      })()}
    </div>
  );
};

export default MyComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

4.4 Ehdolliset renderöintikomponentit

Ehdollisen renderöintilogiikan kapseloiminen erillisiin komponentteihin voi parantaa koodin luettavuutta ja uudelleenkäytettävyyttä.

import React from 'react';

const Greeting = ({ isLoggedIn }) => {
  if (isLoggedIn) {
    return <p>Welcome back!</p>;
  } else {
    return <p>Please sign in.</p>;
  }
};

const MyComponent = () => {
  const isLoggedIn = true;

  return (
    <div>
      <Greeting isLoggedIn={isLoggedIn} />
    </div>
  );
};

export default MyComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

5. Reagoi perustapahtuman sitomiseen

5.1 Perustapahtuman sitominen

Reactissa tapahtumakäsittelijät voidaan sitoa suoraan JSX:ään HTML-kaltaisella tavalla. Sido esimerkiksi napsautustapahtuma painikkeeseen:

import React from 'react';

const MyComponent = () => {
  const handleClick = () => {
    console.log('Button clicked!');
  };

  return (
    <div>
      <button onClick={handleClick}>Click me</button>
    </div>
  );
};

export default MyComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

Tässä esimerkissäonClick On Reactin tapahtumaominaisuus, joka vastaanottaa funktion arvona. Kun painiketta napsautetaan,handleClick Toimintoa kutsutaan.

5.2 Tapahtumankäsittelytoiminto

Reactin tapahtumankäsittelytoiminnot ovat samanlaisia ​​kuin tavalliset JavaScript-tapahtumankäsittelytoiminnot. Ne vastaanottavat synteettisen tapahtumaobjektin (SyntheticEvent) alkuperäisen DOM-tapahtumaobjektin sijaan. Tämä tekee tapahtumien käsittelystä eri selaimissa johdonmukaisemman ja luotettavamman.

import React from 'react';

const MyComponent = () => {
  const handleClick = (event) => {
    console.log('Button clicked!', event.target);
  };

  return (
    <div>
      <button onClick={handleClick}>Click me</button>
    </div>
  );
};

export default MyComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

Yllä olevassa esimerkissähandleClick toimintoparametrejaevent on synteettinen tapahtumaobjekti, joka voidaan välittääevent.target Käytä DOM-elementtiä, joka käynnisti tapahtuman.

5.3 Tapahtumaparametrien välitys

Joskus on tarpeen välittää lisäparametreja tapahtumakäsittelijätoiminnolle.Voit käyttää nuolitoimintoja taibind menetelmä tämän saavuttamiseksi.

Käytä nuolifunktioita:

import React from 'react';

const MyComponent = () => {
  const handleClick = (name) => {
    console.log(`Hello, ${name} clicked!`);
  };

  return (
    <div>
      <button onClick={() => handleClick('World')}>Click me</button>
    </div>
  );
};

export default MyComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

käyttää bind menetelmä:

import React from 'react';

const MyComponent = () => {
  const handleClick = (name) => {
    console.log(`Hello, ${name} clicked!`);
  };

  return (
    <div>
      <button onClick={handleClick.bind(null, 'World')}>Click me</button>
    </div>
  );
};

export default MyComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

Molemmat menetelmät voivat olla 'World' välitetty parametrinahandleClick toiminto.

5.4 Estä tapahtuman oletuskäyttäytyminen ja kupliminen

Reactissa oletuskäyttäytymisen ja tapahtumien kuplimisen estäminen voidaan saavuttaa synteettisten tapahtumaobjektien menetelmillä.

Estä oletuskäyttäytyminen:

import React from 'react';

const MyComponent = () => {
  const handleClick = (event) => {
    event.preventDefault();
    console.log('Button clicked!');
  };

  return (
    <div>
      <a href="#" onClick={handleClick}>Click me</a>
    </div>
  );
};

export default MyComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

Lopeta kupliminen:

import React from 'react';

const MyComponent = () => {
  const handleClick = (event) => {
    event.stopPropagation();
    console.log('Button clicked!');
  };

  return (
    <div onClick={() => console.log('Div clicked!')}>
      <button onClick={handleClick}>Click me</button>
    </div>
  );
};

export default MyComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

Tee yhteenveto

Reactin tapahtumien sidonta ja käsittely eroavat hieman perinteisestä JavaScript-tapahtuman käsittelystä, mikä näkyy pääasiassa tapahtumaobjektien käsittelyssä, jossa käytetään synteettisiä tapahtumaobjekteja selainten välisen johdonmukaisuuden saavuttamiseksi. Yllä olevan menetelmän avulla Reactissa voidaan käsitellä tehokkaasti erilaisia ​​tapahtumia ja suorittaa toimintoja, kuten tapahtumaparametrien välitys, oletuskäyttäytymisen estäminen ja kupliminen.

6. Mitä ovat komponentit?

Reactissa komponentit ovat käyttöliittymien rakentamisen perusyksiköitä ja käyttöliittymä voidaan jakaaItsenäiset, uudelleen käytettävät koodinpätkät . Komponentit voivat olla funktiokomponentteja tai luokkakomponentteja, jotka vastaanottavat syötetietoja (kutsutaan propsiksi) ja palauttavat React-elementtejä, jotka kuvaavat sivulla näkyvää sisältöä. Komponentit voivat sisältää muita komponentteja, HTML-tageja ja logiikkaa, jotta monimutkaisia ​​käyttöliittymiä voidaan hallita ja kehittää tehokkaasti.

Pääominaisuudet ja toiminnot:

  1. Kapselointi ja uudelleenkäyttö
    • Komponentit voivat jakaa käyttöliittymän itsenäisiin osiin, joista jokainen vastaa omasta toiminnastaan, mikä parantaa koodin ylläpidettävyyttä ja uudelleenkäytettävyyttä.
  2. komponenttihierarkia
    • Komponentit voidaan sisäkkäin ja yhdistää muodostamaan hierarkkinen rakenne. Emokomponentit voivat välittää tietoja ja toimintoja lapsikomponenteille tiedonkulun ja vuorovaikutustoimintojen toteuttamiseksi.
  3. Statushallinta
    • Luokkakomponenteilla voi olla tila, jota käytetään tietojen tallentamiseen ja hallintaan komponentin sisällä. Tilamuutokset käynnistävät komponentin uudelleenmuodostamisen, mikä päivittää käyttöliittymän.
  4. elinkaari
    • Luokkakomponenteilla on elinkaarimenetelmiä, kuten componentDidMountcomponentDidUpdate jacomponentWillUnmount jne., joita käytetään tietyn logiikan suorittamiseen komponenttien elinkaaren eri vaiheissa.
  5. Puhtaat käyttöliittymäkomponentit ja konttikomponentit
    • Puhtaat käyttöliittymäkomponentit (Presentational Components) vastaavat tietojen hahmontamisesta, eivätkä ne sisällä liiketoimintalogiikkaa. Container Components on vastuussa tietojen ja tilan hallinnasta ja niiden välittämisestä puhtaille käyttöliittymäkomponenteille.

Esimerkki:

Tässä on esimerkki yksinkertaisesta React-funktiokomponentista, joka näyttää komponentin nimeltä HelloWorld komponentti, joka vastaanottaa aname attribuutti syötteenä ja tekee yksinkertaisen tervehdyslauseen:

import React from 'react';

// 函数组件:HelloWorld
const HelloWorld = ({ name }) => {
  return (
    <div>
      <h1>Hello, {name}!</h1>
      <p>Welcome to React components.</p>
    </div>
  );
};

export default HelloWorld;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

Tässä esimerkissäHelloWorld Komponentti vastaanottaa aname Ominaisuus tervehdysten dynaamiseen näyttämiseen.Tätä komponenttia voidaan käyttää useita kertoja, ja se välittää eri arvoja joka kerta, kun sitä käytetään.name Attribuuttien avulla käyttöliittymässä näkyvää tervehdystä voidaan mukauttaa.

Lyhyesti sanottuna React-komponentit ovat yksi nykyaikaisten verkkosovellusten rakentamisen ydinkonsepteista. Niiden koostumus ja abstraktio antavat kehittäjille mahdollisuuden rakentaa käyttöliittymiä tehokkaammin ja joustavammin.

7. Johdatus useStateen

useState Se on Hook in React, jota käytetään lisäämään tilanhallintatoimintoja toimintokomponentteihin. Sen avulla voit ilmoittaa tilamuuttujat toiminnallisissa komponenteissa ja tarjoaa menetelmän näiden tilojen päivittämiseen.

Ohjeet

useState tuodaan Reactista ja sitä kutsutaan yleensä toiminnallisen komponentin yläosassa. Se palauttaa taulukon, joka sisältää kaksi elementtiä: nykyisen tilan arvon ja funktion, joka päivittää tilan.

perusesimerkki

import React, { useState } from 'react';

const Counter = () => {
  // 声明一个名为 "count" 的状态变量,初始值为 0
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
};

export default Counter;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

Tässä esimerkissä:

  • const [count, setCount] = useState(0); ilmoittaa tiedoston nimeltäcount Tilamuuttuja, alkuarvo on0useState Palauttaa taulukon, ensimmäinen elementti on nykyisen tilan arvo (count), toinen elementti on toiminto, joka päivittää tilan (setCount)。
  • Soita joka kerta, kun painiketta napsautetaan setCount(count + 1) uusiacount arvo, käynnistää komponentin uudelleenhahmontamisen ja päivittää näytettyjen napsautusten määrän.

Käytä useita tilamuuttujia

Voit käyttää useita useState Kutsutaan hallitsemaan erilaisia ​​tilamuuttujia:

import React, { useState } from 'react';

const MultiStateComponent = () => {
  const [count, setCount] = useState(0);
  const [text, setText] = useState('');

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
      <input
        type="text"
        value=
                    
                        
                    
                    

React基础学习-Day01

1.React介绍

1.1 react是什么?

React 是一个用于构建用户界面的开源 JavaScript 库,由 Facebook 开发和维护。自 2013 年开源以来,React 已成为前端开发的热门选择,广泛应用于单页应用(SPA)和复杂的多页应用的开发。React 的主要目标是简化 UI 开发,使其更加高效、灵活和可维护。

1.2 react的优势?

1.2.1 react对比DOM的优势体现
  1. 虚拟 DOM 和高效更新
    • 虚拟 DOM:React 使用虚拟 DOM 作为内存中的副本来表示 UI 结构。每次数据更新时,React 首先在虚拟 DOM 中进行计算和比较,然后再将变化的部分批量更新到实际 DOM 中。这种优化能够显著减少 DOM 操作,提升性能。
    • 减少重绘和回流:通过虚拟 DOM,React 可以避免频繁地直接操作实际 DOM,减少页面重绘(repaint)和回流(reflow),从而提高页面的响应速度和性能。
  2. 组件化和可复用性
    • 组件化:React 鼓励将 UI 拆分为独立的组件,每个组件负责自己的 UI 和逻辑。这种模块化的设计使得开发者可以更容易地复用、测试和维护代码。
    • 自定义组件:开发者可以创建自定义的组件,并通过组合这些组件来构建复杂的 UI。这种灵活性和可复用性是传统 DOM 操作所不具备的。
  3. 声明式编程风格
    • 声明式:React 的编程风格是声明式的,开发者只需描述 UI 应该是什么样子,而不需要关心如何操作 DOM 进行更新。这种方式更加直观和易于理解,提高了代码的可维护性。
    • 数据驱动:React 强调通过状态(state)和属性(props)来驱动 UI 的变化,数据变化时,React 负责更新 UI,开发者无需手动操作 DOM。
  4. 跨平台能力
    • React Native:除了 Web 应用外,React 还支持使用相同的组件模型构建原生移动应用。React Native 提供了一种在 iOS 和 Android 上构建高性能、原生用户界面的方式,这使得开发者可以共享大部分代码和技能,减少开发成本和学习曲线。
  5. 社区和生态系统支持
    • 庞大的社区:React 拥有一个活跃和庞大的社区,提供了丰富的第三方库、工具和解决方案,帮助开发者更高效地开发和部署应用。
    • 组件库:有许多优秀的 UI 组件库(如 Material-UI、Ant Design 等)和状态管理工具(如 Redux、MobX 等),可以与 React 配合使用,进一步提升开发效率和应用性能。

总结来说,React 相对于传统的 DOM 操作,通过虚拟 DOM、组件化、声明式编程等特性,提供了更高效、可维护和可扩展的开发方式。这些优势使得 React 成为前端开发中的主流框架之一,被广泛应用于各种规模和类型的项目中。

1.2.2 react与其他框架的对比
  1. 灵活性和可定制性
    • React:React 本身是一个库而非完整的框架,它更注重于提供构建用户界面的核心工具和机制,开发者可以自由选择配合使用其他库和工具(如 Redux、React Router 等)。这种灵活性使得开发者可以根据项目需求进行更精确的定制和优化。
    • Vue.js:Vue.js 提供了更全面的解决方案,包括路由、状态管理和构建工具等,对于小型到中型应用,Vue.js 提供了更多开箱即用的功能,减少了集成和配置的复杂性。
  2. 虚拟 DOM 的实现
    • React:React 使用了一套高效的虚拟 DOM 和 diff 算法,这使得 React 在处理大型数据集合和频繁数据更新时性能表现优越。
    • Vue.js:Vue.js 也使用了类似的虚拟 DOM 技术,但在一些测试中,React 的 diff 算法可能会更快一些,尤其是在处理复杂的 UI 更新时。
  3. 生态系统和社区支持
    • React:React 拥有一个庞大和活跃的社区,支持丰富的第三方库和工具,如 Redux、Material-UI 等,这些库能够帮助开发者构建复杂的单页应用和大型项目。
    • Vue.js:Vue.js 社区同样非常活跃,Vue.js 生态系统提供了许多插件和工具,如 Vuex(状态管理)、Vue Router(路由管理)等,为开发者提供了更多的选择和集成方案。
  4. 学习曲线和易用性
    • React:React 的学习曲线相对较陡,特别是对于初学者来说,需要掌握 JSX、组件生命周期、状态管理等概念。但一旦掌握了 React 的核心概念,开发者可以更高效地构建和维护复杂的应用。
    • Vue.js:Vue.js 的学习曲线相对平缓,它更接近传统的 HTML、CSS 和 JavaScript,对于有经验的开发者和新手来说都较为友好。Vue.js 的文档和教程也很全面,帮助开发者快速入门和上手。
  5. 社区文化和响应性
    • React:React 社区倾向于更加注重性能和灵活性,也更倾向于使用 TypeScript 等类型安全的技术栈。Facebook 作为 React 的主要维护者,对于安全性和稳定性有较高的保障。
    • Vue.js:Vue.js 社区更加开放和友好,注重开发者体验和易用性。Vue.js 也更容易与其他技术栈集成,比如可以很方便地与现有的项目或库整合。

总体来说,React 和 Vue.js 都是优秀的前端开发框架,选择适合的框架取决于项目需求、团队技术栈和开发者的偏好。React 在大型和复杂的应用中可能更适合,特别是需要高度灵活性和可定制性的场景;而 Vue.js 则更适合于快速开发和中小型应用,提供了更多集成和便捷的解决方案。

1.2.3 react对比DOM如何减少重绘和重排

重绘 (Repaint) 和回流 (Reflow)

  1. 重绘 (Repaint):当元素的外观样式(如颜色、背景、可见性)发生变化,但不影响布局时,会触发重绘。
  2. 回流 (Reflow):当元素的尺寸、位置或结构发生变化,影响布局时,会触发回流。回流比重绘更耗费性能,因为需要重新计算布局和渲染树。

React 如何减少重绘和回流

  1. 虚拟 DOM (Virtual DOM)
    • 虚拟 DOM:React 创建了一个虚拟 DOM,它是 UI 的轻量级副本,保存在内存中。每次组件的状态或属性发生变化时,React 会在虚拟 DOM 中进行计算和比较,生成新的虚拟 DOM 树。
    • Diff 算法:React 使用高效的 diff 算法比较新旧虚拟 DOM 树,找出变化的部分,并生成一个更新补丁。
  2. 最小化实际 DOM 操作
    • 批量更新:React 将多个状态更新合并为一次批量更新,减少 DOM 操作次数。批量更新通过一次性更新多个变化,避免频繁操作 DOM 导致的性能损耗。
    • 异步更新:React 通过异步批处理(例如 React 18 中引入的 Concurrent Mode),将多次状态更新合并处理,避免频繁的同步 DOM 操作。
  3. 避免不必要的更新
    • shouldComponentUpdate:类组件中可以使用 shouldComponentUpdate 方法来控制组件是否需要重新渲染,从而避免不必要的重绘和回流。
    • React.memo:函数组件可以使用 React.memo 进行性能优化,它会对比前后属性,只有属性变化时才会重新渲染组件。
    • useMemouseCallback:Hooks 提供的 useMemouseCallback 可以缓存计算结果和函数引用,避免子组件不必要的更新。
  4. 合并更新
    • 批量状态更新:React 会自动合并多次状态更新,在一次事件循环内只触发一次渲染,从而减少 DOM 操作。

示例代码

以下示例演示了 React 如何通过 React.memouseMemo 来减少不必要的渲染:

import React, { useState, useMemo } from 'react';

// 一个简单的子组件,仅在 props 变化时重新渲染
const ChildComponent = React.memo(({ value }) => {
  console.log('ChildComponent render');
  return <div>{value}</div>;
});

function App() {
  const [count, setCount] = useState(0);
  const [text, setText] = useState('');

  // 使用 useMemo 缓存计算结果,避免不必要的计算
  const memoizedValue = useMemo(() => {
    console.log('Calculating memoized value');
    return count * 2;
  }, [count]);

  return (
    <div>
      <h1>Count: {count}</h1>
      <button onClick={() => setCount(count + 1)}>Increment</button>
      <input 
        type="text" 
        value={text} 
        onChange={(e) => setText(e.target.value)} 
      />
      <ChildComponent value={memoizedValue} />
    </div>
  );
}

export default App;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

在这个示例中:

  • ChildComponent 只有在 value 变化时才会重新渲染,因为它被 React.memo 包裹。
  • memoizedValue 使用 useMemo 进行缓存,只有在 count 变化时才会重新计算,避免了不必要的计算和渲染。

总结

通过虚拟 DOM、批量更新、避免不必要的更新和合并更新,React 有效地减少了重绘和回流的次数,从而提升了应用的性能。与传统的直接操作 DOM 的方式相比,React 提供了一种更加高效和优化的 UI 更新机制。

2.jsx语法介绍

.jsxJavaScript XML 的缩写,它是一种 JavaScript 的语法扩展,允许开发者在 JavaScript 中直接编写类似 HTML 的标记语言,用于定义 React 组件的 UI 结构。以下是一些 .jsx 语法的核心特点和使用方法:

主要特点:

  1. 类 HTML 结构
    • .jsx 允许在 JavaScript 中嵌入类似 HTML 的标记语言,用于声明 UI 的结构和组件的外观。
    • 例如,在 React 中,可以直接使用 <div><span><h1> 等 HTML 标签,以及自定义的 React 组件。
  2. JSX 表达式
    • .jsx 中,可以使用 {} 花括号来包裹 JavaScript 表达式,用于在标记中动态地插入变量、计算结果或函数调用。
    • 这使得 .jsx 具有了 JavaScript 的全部表达能力,可以进行条件判断、循环、计算等操作。
  3. 属性传递
    • 类似 HTML,.jsx 允许在标签上使用属性,并支持使用表达式作为属性值。
    • 例如:<Component name={variable} />,其中 name 是一个属性,variable 是一个 JavaScript 变量或表达式。
  4. 自闭合标签
    • .jsx 中的标签可以是自闭合的,比如 <img><input>,也可以使用 / 符号来表示自闭合,例如 <br />
  5. 注释
    • 和 JavaScript 一样,可以使用 // 单行注释和 /* */ 多行注释在 .jsx 文件中添加注释(注释要写在{}内)。

示例:

以下是一个简单的 React 组件示例,展示了 .jsx 的基本语法和特点:

import React from 'react';

// 定义一个 React 函数组件
const MyComponent = () => {
  const name = 'World';

  return (
    <div>
      <h1>Hello, {name}!</h1>
      <p>Welcome to JSX!</p>
      <ul>
        {['apple', 'banana', 'cherry'].map((fruit, index) => (
          <li key={index}>{fruit}</li>
        ))}
      </ul>
    </div>
  );
};

export default MyComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

在这个例子中:

  • <h1><p><ul><li> 等标签直接在 JavaScript 函数中使用,用于构建组件的 UI 结构。
  • 使用 {name}<h1> 中动态地插入变量 name 的值。
  • 使用 {} 花括号包裹的 JavaScript 表达式,例如 ['apple', 'banana', 'cherry'].map() 来生成列表项 <li>
  • key={index} 用于在 React 中标识列表项的唯一性,帮助 React 更高效地管理组件的更新。

注意事项:

  • JSX 本质上是 JavaScript 语法的扩展,需要通过 Babel 等工具进行编译转换成标准的 JavaScript 代码,以便浏览器能够正确解析和执行。
  • JSX 让开发者可以更直观地编写和理解 React 组件的结构和逻辑,提高了代码的可读性和开发效率。

总结来说,.jsx 是 React 中用于定义组件 UI 结构的一种语法扩展,它结合了 JavaScript 的表达能力和 HTML 标记的直观性,是开发现代 Web 应用的重要工具之一。

3.jsx实现列表渲染

import React from 'react';

const MyComponent = () => {
  // 假设我们有一个水果列表
  const fruits = ['apple', 'banana', 'cherry'];

  return (
    <div>
      <h2>Fruit List:</h2>
      <ul>
        {/* 使用 map 方法遍历数组,并为每个元素生成一个 <li> 元素 */}
        {fruits.map((fruit, index) => (
          <li key={index}>{fruit}</li>
        ))}
      </ul>
    </div>
  );
};

export default MyComponent;

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

4.jsx实现条件渲染

4.1 三元运算符 (Ternary Operator)

这是最常用的方式,通过三元运算符来实现简单的条件渲染。

import React from 'react';

const MyComponent = () => {
  const isLoggedIn = true;

  return (
    <div>
      {isLoggedIn ? <p>Welcome back!</p> : <p>Please sign in.</p>}
    </div>
  );
};

export default MyComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

4.2. 逻辑与运算符 (Logical AND Operator)

适用于条件为真时才渲染内容的场景。

import React from 'react';

const MyComponent = () => {
  const isLoggedIn = true;

  return (
    <div>
      {isLoggedIn && <p>Welcome back!</p>}
    </div>
  );
};

export default MyComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

4.3. 立即执行函数表达式 (IIFE)

适用于需要执行更多逻辑或多条件判断的情况。

import React from 'react';

const MyComponent = () => {
  const status = 'loggedOut'; // 可以是 'loggedIn' 或 'loggedOut'

  return (
    <div>
      {(() => {
        if (status === 'loggedIn') {
          return <p>Welcome back!</p>;
        } else if (status === 'loggedOut') {
          return <p>Please sign in.</p>;
        } else {
          return <p>Status unknown.</p>;
        }
      })()}
    </div>
  );
};

export default MyComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

4.4 条件渲染组件

将条件渲染逻辑封装到单独的组件中,可以提高代码的可读性和复用性。

import React from 'react';

const Greeting = ({ isLoggedIn }) => {
  if (isLoggedIn) {
    return <p>Welcome back!</p>;
  } else {
    return <p>Please sign in.</p>;
  }
};

const MyComponent = () => {
  const isLoggedIn = true;

  return (
    <div>
      <Greeting isLoggedIn={isLoggedIn} />
    </div>
  );
};

export default MyComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

5.React基础事件绑定

5.1 基本事件绑定

在 React 中,可以直接在 JSX 中通过类似 HTML 的方式来绑定事件处理函数。例如,给按钮绑定点击事件:

import React from 'react';

const MyComponent = () => {
  const handleClick = () => {
    console.log('Button clicked!');
  };

  return (
    <div>
      <button onClick={handleClick}>Click me</button>
    </div>
  );
};

export default MyComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

在这个例子中,onClick 是 React 的事件属性,它接收一个函数作为值。当按钮被点击时,handleClick 函数会被调用。

5.2 事件处理函数

React 的事件处理函数与普通的 JavaScript 事件处理函数类似,它们接收一个合成事件对象 (SyntheticEvent),而不是原生 DOM 事件对象。这使得跨浏览器的事件处理更加一致和可靠。

import React from 'react';

const MyComponent = () => {
  const handleClick = (event) => {
    console.log('Button clicked!', event.target);
  };

  return (
    <div>
      <button onClick={handleClick}>Click me</button>
    </div>
  );
};

export default MyComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

在上面的示例中,handleClick 函数的参数 event 是一个合成事件对象,可以通过 event.target 访问触发事件的 DOM 元素。

5.3 事件传参

有时候需要给事件处理函数传递额外的参数。可以使用箭头函数或者 bind 方法来实现这一点。

使用箭头函数:

import React from 'react';

const MyComponent = () => {
  const handleClick = (name) => {
    console.log(`Hello, ${name} clicked!`);
  };

  return (
    <div>
      <button onClick={() => handleClick('World')}>Click me</button>
    </div>
  );
};

export default MyComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

使用 bind 方法:

import React from 'react';

const MyComponent = () => {
  const handleClick = (name) => {
    console.log(`Hello, ${name} clicked!`);
  };

  return (
    <div>
      <button onClick={handleClick.bind(null, 'World')}>Click me</button>
    </div>
  );
};

export default MyComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

这两种方式都可以将 'World' 作为参数传递给 handleClick 函数。

5.4 阻止事件默认行为和冒泡

在 React 中,阻止事件的默认行为和冒泡可以通过合成事件对象的方法来实现。

阻止默认行为:

import React from 'react';

const MyComponent = () => {
  const handleClick = (event) => {
    event.preventDefault();
    console.log('Button clicked!');
  };

  return (
    <div>
      <a href="#" onClick={handleClick}>Click me</a>
    </div>
  );
};

export default MyComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

阻止冒泡:

import React from 'react';

const MyComponent = () => {
  const handleClick = (event) => {
    event.stopPropagation();
    console.log('Button clicked!');
  };

  return (
    <div onClick={() => console.log('Div clicked!')}>
      <button onClick={handleClick}>Click me</button>
    </div>
  );
};

export default MyComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

总结

React 的事件绑定和处理与传统的 JavaScript 事件处理有些许差异,主要体现在事件对象的处理上,使用合成事件对象来实现跨浏览器一致性。通过上述方法,可以有效地在 React 中处理各种事件,并进行事件传参、阻止默认行为和冒泡等操作。

6.组件是什么?

在 React 中,组件是构建用户界面的基本单位,可以将 UI 分割成独立的、可复用的代码片段。组件可以是函数组件或类组件,它们可以接收输入的数据(称为 props)并返回描述页面展示内容的 React 元素。组件可以包含其他组件、HTML 标签和逻辑,使得复杂的 UI 可以被有效地管理和开发。

主要特点和作用:

  1. 封装和复用
    • 组件可以将 UI 划分成独立的部分,每个部分负责自己的功能,从而提高代码的可维护性和复用性。
  2. 组件层级
    • 组件可以嵌套组合,形成层次化的结构。父组件可以向子组件传递数据和函数,实现数据的流动和交互的功能。
  3. 状态管理
    • 类组件可以拥有状态(state),用于存储和管理组件内部的数据。状态的改变会触发组件的重新渲染,从而更新用户界面。
  4. 生命周期
    • 类组件具有生命周期方法,例如 componentDidMountcomponentDidUpdatecomponentWillUnmount 等,用于在组件生命周期不同阶段执行特定的逻辑。
  5. 纯UI组件和容器组件
    • 纯UI组件(Presentational Components)负责如何渲染数据,不涉及业务逻辑。容器组件(Container Components)则负责管理数据和状态,传递给纯UI组件。

示例:

以下是一个简单的 React 函数组件的示例,展示了一个名为 HelloWorld 的组件,它接收一个 name 属性作为输入,并渲染一个简单的问候语句:

import React from 'react';

// 函数组件:HelloWorld
const HelloWorld = ({ name }) => {
  return (
    <div>
      <h1>Hello, {name}!</h1>
      <p>Welcome to React components.</p>
    </div>
  );
};

export default HelloWorld;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

在这个例子中,HelloWorld 组件接收一个 name 属性,用于动态显示问候语。这种组件可以被多次使用,每次使用时传入不同的 name 属性,使得界面呈现的问候语可以个性化定制。

总之,React 组件是构建现代 Web 应用的核心概念之一,它们通过组合和抽象,使得开发者可以更加高效和灵活地构建用户界面。

7.useState使用介绍

useState 是 React 中的一个 Hook,用于在函数组件中添加状态管理功能。它允许你在函数组件中声明状态变量,并提供一个方法来更新这些状态。

使用方法

useState 是从 React 中导入的,并且通常在函数组件的顶部进行调用。它返回一个包含两个元素的数组:当前状态值和一个更新状态的函数。

基本示例

import React, { useState } from 'react';

const Counter = () => {
  // 声明一个名为 "count" 的状态变量,初始值为 0
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
};

export default Counter;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

在这个示例中:

  • const [count, setCount] = useState(0); 声明了一个名为 count 的状态变量,初始值为 0useState 返回一个数组,第一个元素是当前状态值(count),第二个元素是更新状态的函数(setCount)。
  • 每次点击按钮时,调用 setCount(count + 1) 更新 count 的值,从而触发组件的重新渲染,并更新显示的点击次数。

使用多个状态变量

你可以在一个组件中使用多个 useState 调用来管理不同的状态变量:

import React, { useState } from 'react';

const MultiStateComponent = () => {
  const [count, setCount] = useState(0);
  const [text, setText] = useState('');

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
      <input
        type="text"
        value={text}
        onChange={(e) => setText(e.target.value)}
        placeholder="Type something..."
      />
      <p>You typed: {text}</p>
    </div>
  );
};

export default MultiStateComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

在这个示例中,我们使用了两个 useState 调用来分别管理 counttext 两个状态变量。

初始化状态

你可以将状态的初始值设置为函数返回的值,这在初始化需要执行复杂计算时特别有用:

import React, { useState } from 'react';

const ExpensiveComponent = () => {
  const initialCount = () => {
    // 模拟一个复杂的计算
    return 42;
  };

  const [count, setCount] = useState(initialCount);

  return (
    <div>
      <p>Initial count: {count}</p>
      <button onClick={() => setCount(count + 1)}>
        Increment
      </button>
    </div>
  );
};

export default ExpensiveComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

在这个示例中,initialCount 函数只会在组件初次渲染时执行一次,用于计算初始状态值。

总结

  • useState 是一个 React Hook,用于在函数组件中添加状态管理功能。
  • useState 返回一个包含当前状态值和一个更新状态的函数的数组。
  • 可以使用多个 useState 调用来管理多个状态变量。
  • 状态的初始值可以是一个复杂计算的结果,通过传递一个函数来实现。

8.修改状态的规则

在 React 中,使用 useState 来管理和修改状态时,有一些规则和最佳实践需要遵循,以确保状态的管理和更新过程是高效和可靠的。以下是修改状态的主要规则和一些示例:

1. 状态更新是异步的

React 的状态更新是异步的,这意味着调用状态更新函数后,状态的更新不会立即反映出来,而是在下一次重新渲染时才会生效。

import React, { useState } from 'react';

const Counter = () => {
  const [count, setCount] = useState(0);

  const handleClick = () => {
    setCount(count + 1);
    console.log(count); // 这里的 count 可能不会立即更新
  };

  return (
    <div>
      <p>{count}</p>
      <button onClick={handleClick}>Increment</button>
    </div>
  );
};

export default Counter;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

在上述例子中,console.log(count) 可能不会立即显示更新后的值,因为状态更新是异步的。

2. 状态更新函数接受当前状态作为参数

为了确保状态更新时使用的值是最新的,可以传递一个函数给状态更新函数。这个函数会接收当前的状态值作为参数。

import React, { useState } from 'react';

const Counter = () => {
  const [count, setCount] = useState(0);

  const handleClick = () => {
    setCount(prevCount => prevCount + 1);
  };

  return (
    <div>
      <p>{count}</p>
      <button onClick={handleClick}>Increment</button>
    </div>
  );
};

export default Counter;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

在这个示例中,setCount 接收一个函数 prevCount => prevCount + 1,确保使用的是最新的状态值进行更新。

3. 不要直接修改状态

状态应该是不可变的,不要直接修改状态对象,而是通过创建新对象来更新状态。

import React, { useState } from 'react';

const Example = () => {
  const [user, setUser] = useState({ name: 'John', age: 30 });

  const updateAge = () => {
    setUser(prevUser => ({
      ...prevUser,
      age: prevUser.age + 1
    }));
  };

  return (
    <div>
      <p>{user.name}</p>
      <p>{user.age}</p>
      <button onClick={updateAge}>Increment Age</button>
    </div>
  );
};

export default Example;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

在这个示例中,使用扩展运算符 ...prevUser 创建了一个新的用户对象,并更新了年龄属性。

4. 合并状态

对于对象类型的状态,需要手动合并更新的部分,因为 useState 不会自动合并更新对象。

import React, { useState } from 'react';

const Example = () => {
  const [user, setUser] = useState({ name: 'John', age: 30 });

  const updateName = () => {
    setUser(prevUser => ({
      ...prevUser,
      name: 'Doe'
    }));
  };

  return (
    <div>
      <p>{user.name}</p>
      <p>{user.age}</p>
      <button onClick={updateName}>Update Name</button>
    </div>
  );
};

export default Example;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

在这个示例中,setUser 的更新函数创建了一个新的用户对象,同时保持其他属性不变。

5. 避免不必要的状态更新

尽量避免在每次渲染中都调用状态更新函数,只有在需要时才更新状态,以提高性能。

import React, { useState } from 'react';

const Example = () => {
  const [count, setCount] = useState(0);

  const handleClick = () => {
    if (count < 10) {
      setCount(count + 1);
    }
  };

  return (
    <div>
      <p>{count}</p>
      <button onClick={handleClick}>Increment</button>
    </div>
  );
};

export default Example;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

在这个示例中,只有在 count 小于 10 时才会更新状态,避免了不必要的状态更新。

总结

  1. 状态更新是异步的:不能依赖立即更新后的值。
  2. 使用函数式更新:在更新状态时,传递一个函数来确保使用最新的状态值。
  3. 不要直接修改状态:状态应该是不可变的,需要通过创建新对象来更新状态。
  4. 手动合并状态:对于对象类型的状态,需要手动合并更新部分。
  5. 避免不必要的状态更新:只有在需要时才更新状态,以提高性能。

9.基础样式方案

1.行内样式(不推荐):<div style={{color:“red”}}></>

2.class类名控制:

10.classNames优化类名控制

<div className={classNames(“foo”,{active:true})}>

onChange={(e) => setText(e.target.value)} placeholder="Type something..." /> <p>You typed:

React基础学习-Day01

1.React介绍

1.1 react是什么?

React 是一个用于构建用户界面的开源 JavaScript 库,由 Facebook 开发和维护。自 2013 年开源以来,React 已成为前端开发的热门选择,广泛应用于单页应用(SPA)和复杂的多页应用的开发。React 的主要目标是简化 UI 开发,使其更加高效、灵活和可维护。

1.2 react的优势?

1.2.1 react对比DOM的优势体现
  1. 虚拟 DOM 和高效更新
    • 虚拟 DOM:React 使用虚拟 DOM 作为内存中的副本来表示 UI 结构。每次数据更新时,React 首先在虚拟 DOM 中进行计算和比较,然后再将变化的部分批量更新到实际 DOM 中。这种优化能够显著减少 DOM 操作,提升性能。
    • 减少重绘和回流:通过虚拟 DOM,React 可以避免频繁地直接操作实际 DOM,减少页面重绘(repaint)和回流(reflow),从而提高页面的响应速度和性能。
  2. 组件化和可复用性
    • 组件化:React 鼓励将 UI 拆分为独立的组件,每个组件负责自己的 UI 和逻辑。这种模块化的设计使得开发者可以更容易地复用、测试和维护代码。
    • 自定义组件:开发者可以创建自定义的组件,并通过组合这些组件来构建复杂的 UI。这种灵活性和可复用性是传统 DOM 操作所不具备的。
  3. 声明式编程风格
    • 声明式:React 的编程风格是声明式的,开发者只需描述 UI 应该是什么样子,而不需要关心如何操作 DOM 进行更新。这种方式更加直观和易于理解,提高了代码的可维护性。
    • 数据驱动:React 强调通过状态(state)和属性(props)来驱动 UI 的变化,数据变化时,React 负责更新 UI,开发者无需手动操作 DOM。
  4. 跨平台能力
    • React Native:除了 Web 应用外,React 还支持使用相同的组件模型构建原生移动应用。React Native 提供了一种在 iOS 和 Android 上构建高性能、原生用户界面的方式,这使得开发者可以共享大部分代码和技能,减少开发成本和学习曲线。
  5. 社区和生态系统支持
    • 庞大的社区:React 拥有一个活跃和庞大的社区,提供了丰富的第三方库、工具和解决方案,帮助开发者更高效地开发和部署应用。
    • 组件库:有许多优秀的 UI 组件库(如 Material-UI、Ant Design 等)和状态管理工具(如 Redux、MobX 等),可以与 React 配合使用,进一步提升开发效率和应用性能。

总结来说,React 相对于传统的 DOM 操作,通过虚拟 DOM、组件化、声明式编程等特性,提供了更高效、可维护和可扩展的开发方式。这些优势使得 React 成为前端开发中的主流框架之一,被广泛应用于各种规模和类型的项目中。

1.2.2 react与其他框架的对比
  1. 灵活性和可定制性
    • React:React 本身是一个库而非完整的框架,它更注重于提供构建用户界面的核心工具和机制,开发者可以自由选择配合使用其他库和工具(如 Redux、React Router 等)。这种灵活性使得开发者可以根据项目需求进行更精确的定制和优化。
    • Vue.js:Vue.js 提供了更全面的解决方案,包括路由、状态管理和构建工具等,对于小型到中型应用,Vue.js 提供了更多开箱即用的功能,减少了集成和配置的复杂性。
  2. 虚拟 DOM 的实现
    • React:React 使用了一套高效的虚拟 DOM 和 diff 算法,这使得 React 在处理大型数据集合和频繁数据更新时性能表现优越。
    • Vue.js:Vue.js 也使用了类似的虚拟 DOM 技术,但在一些测试中,React 的 diff 算法可能会更快一些,尤其是在处理复杂的 UI 更新时。
  3. 生态系统和社区支持
    • React:React 拥有一个庞大和活跃的社区,支持丰富的第三方库和工具,如 Redux、Material-UI 等,这些库能够帮助开发者构建复杂的单页应用和大型项目。
    • Vue.js:Vue.js 社区同样非常活跃,Vue.js 生态系统提供了许多插件和工具,如 Vuex(状态管理)、Vue Router(路由管理)等,为开发者提供了更多的选择和集成方案。
  4. 学习曲线和易用性
    • React:React 的学习曲线相对较陡,特别是对于初学者来说,需要掌握 JSX、组件生命周期、状态管理等概念。但一旦掌握了 React 的核心概念,开发者可以更高效地构建和维护复杂的应用。
    • Vue.js:Vue.js 的学习曲线相对平缓,它更接近传统的 HTML、CSS 和 JavaScript,对于有经验的开发者和新手来说都较为友好。Vue.js 的文档和教程也很全面,帮助开发者快速入门和上手。
  5. 社区文化和响应性
    • React:React 社区倾向于更加注重性能和灵活性,也更倾向于使用 TypeScript 等类型安全的技术栈。Facebook 作为 React 的主要维护者,对于安全性和稳定性有较高的保障。
    • Vue.js:Vue.js 社区更加开放和友好,注重开发者体验和易用性。Vue.js 也更容易与其他技术栈集成,比如可以很方便地与现有的项目或库整合。

总体来说,React 和 Vue.js 都是优秀的前端开发框架,选择适合的框架取决于项目需求、团队技术栈和开发者的偏好。React 在大型和复杂的应用中可能更适合,特别是需要高度灵活性和可定制性的场景;而 Vue.js 则更适合于快速开发和中小型应用,提供了更多集成和便捷的解决方案。

1.2.3 react对比DOM如何减少重绘和重排

重绘 (Repaint) 和回流 (Reflow)

  1. 重绘 (Repaint):当元素的外观样式(如颜色、背景、可见性)发生变化,但不影响布局时,会触发重绘。
  2. 回流 (Reflow):当元素的尺寸、位置或结构发生变化,影响布局时,会触发回流。回流比重绘更耗费性能,因为需要重新计算布局和渲染树。

React 如何减少重绘和回流

  1. 虚拟 DOM (Virtual DOM)
    • 虚拟 DOM:React 创建了一个虚拟 DOM,它是 UI 的轻量级副本,保存在内存中。每次组件的状态或属性发生变化时,React 会在虚拟 DOM 中进行计算和比较,生成新的虚拟 DOM 树。
    • Diff 算法:React 使用高效的 diff 算法比较新旧虚拟 DOM 树,找出变化的部分,并生成一个更新补丁。
  2. 最小化实际 DOM 操作
    • 批量更新:React 将多个状态更新合并为一次批量更新,减少 DOM 操作次数。批量更新通过一次性更新多个变化,避免频繁操作 DOM 导致的性能损耗。
    • 异步更新:React 通过异步批处理(例如 React 18 中引入的 Concurrent Mode),将多次状态更新合并处理,避免频繁的同步 DOM 操作。
  3. 避免不必要的更新
    • shouldComponentUpdate:类组件中可以使用 shouldComponentUpdate 方法来控制组件是否需要重新渲染,从而避免不必要的重绘和回流。
    • React.memo:函数组件可以使用 React.memo 进行性能优化,它会对比前后属性,只有属性变化时才会重新渲染组件。
    • useMemouseCallback:Hooks 提供的 useMemouseCallback 可以缓存计算结果和函数引用,避免子组件不必要的更新。
  4. 合并更新
    • 批量状态更新:React 会自动合并多次状态更新,在一次事件循环内只触发一次渲染,从而减少 DOM 操作。

示例代码

以下示例演示了 React 如何通过 React.memouseMemo 来减少不必要的渲染:

import React, { useState, useMemo } from 'react';

// 一个简单的子组件,仅在 props 变化时重新渲染
const ChildComponent = React.memo(({ value }) => {
  console.log('ChildComponent render');
  return <div>{value}</div>;
});

function App() {
  const [count, setCount] = useState(0);
  const [text, setText] = useState('');

  // 使用 useMemo 缓存计算结果,避免不必要的计算
  const memoizedValue = useMemo(() => {
    console.log('Calculating memoized value');
    return count * 2;
  }, [count]);

  return (
    <div>
      <h1>Count: {count}</h1>
      <button onClick={() => setCount(count + 1)}>Increment</button>
      <input 
        type="text" 
        value={text} 
        onChange={(e) => setText(e.target.value)} 
      />
      <ChildComponent value={memoizedValue} />
    </div>
  );
}

export default App;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

在这个示例中:

  • ChildComponent 只有在 value 变化时才会重新渲染,因为它被 React.memo 包裹。
  • memoizedValue 使用 useMemo 进行缓存,只有在 count 变化时才会重新计算,避免了不必要的计算和渲染。

总结

通过虚拟 DOM、批量更新、避免不必要的更新和合并更新,React 有效地减少了重绘和回流的次数,从而提升了应用的性能。与传统的直接操作 DOM 的方式相比,React 提供了一种更加高效和优化的 UI 更新机制。

2.jsx语法介绍

.jsxJavaScript XML 的缩写,它是一种 JavaScript 的语法扩展,允许开发者在 JavaScript 中直接编写类似 HTML 的标记语言,用于定义 React 组件的 UI 结构。以下是一些 .jsx 语法的核心特点和使用方法:

主要特点:

  1. 类 HTML 结构
    • .jsx 允许在 JavaScript 中嵌入类似 HTML 的标记语言,用于声明 UI 的结构和组件的外观。
    • 例如,在 React 中,可以直接使用 <div><span><h1> 等 HTML 标签,以及自定义的 React 组件。
  2. JSX 表达式
    • .jsx 中,可以使用 {} 花括号来包裹 JavaScript 表达式,用于在标记中动态地插入变量、计算结果或函数调用。
    • 这使得 .jsx 具有了 JavaScript 的全部表达能力,可以进行条件判断、循环、计算等操作。
  3. 属性传递
    • 类似 HTML,.jsx 允许在标签上使用属性,并支持使用表达式作为属性值。
    • 例如:<Component name={variable} />,其中 name 是一个属性,variable 是一个 JavaScript 变量或表达式。
  4. 自闭合标签
    • .jsx 中的标签可以是自闭合的,比如 <img><input>,也可以使用 / 符号来表示自闭合,例如 <br />
  5. 注释
    • 和 JavaScript 一样,可以使用 // 单行注释和 /* */ 多行注释在 .jsx 文件中添加注释(注释要写在{}内)。

示例:

以下是一个简单的 React 组件示例,展示了 .jsx 的基本语法和特点:

import React from 'react';

// 定义一个 React 函数组件
const MyComponent = () => {
  const name = 'World';

  return (
    <div>
      <h1>Hello, {name}!</h1>
      <p>Welcome to JSX!</p>
      <ul>
        {['apple', 'banana', 'cherry'].map((fruit, index) => (
          <li key={index}>{fruit}</li>
        ))}
      </ul>
    </div>
  );
};

export default MyComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

在这个例子中:

  • <h1><p><ul><li> 等标签直接在 JavaScript 函数中使用,用于构建组件的 UI 结构。
  • 使用 {name}<h1> 中动态地插入变量 name 的值。
  • 使用 {} 花括号包裹的 JavaScript 表达式,例如 ['apple', 'banana', 'cherry'].map() 来生成列表项 <li>
  • key={index} 用于在 React 中标识列表项的唯一性,帮助 React 更高效地管理组件的更新。

注意事项:

  • JSX 本质上是 JavaScript 语法的扩展,需要通过 Babel 等工具进行编译转换成标准的 JavaScript 代码,以便浏览器能够正确解析和执行。
  • JSX 让开发者可以更直观地编写和理解 React 组件的结构和逻辑,提高了代码的可读性和开发效率。

总结来说,.jsx 是 React 中用于定义组件 UI 结构的一种语法扩展,它结合了 JavaScript 的表达能力和 HTML 标记的直观性,是开发现代 Web 应用的重要工具之一。

3.jsx实现列表渲染

import React from 'react';

const MyComponent = () => {
  // 假设我们有一个水果列表
  const fruits = ['apple', 'banana', 'cherry'];

  return (
    <div>
      <h2>Fruit List:</h2>
      <ul>
        {/* 使用 map 方法遍历数组,并为每个元素生成一个 <li> 元素 */}
        {fruits.map((fruit, index) => (
          <li key={index}>{fruit}</li>
        ))}
      </ul>
    </div>
  );
};

export default MyComponent;

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

4.jsx实现条件渲染

4.1 三元运算符 (Ternary Operator)

这是最常用的方式,通过三元运算符来实现简单的条件渲染。

import React from 'react';

const MyComponent = () => {
  const isLoggedIn = true;

  return (
    <div>
      {isLoggedIn ? <p>Welcome back!</p> : <p>Please sign in.</p>}
    </div>
  );
};

export default MyComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

4.2. 逻辑与运算符 (Logical AND Operator)

适用于条件为真时才渲染内容的场景。

import React from 'react';

const MyComponent = () => {
  const isLoggedIn = true;

  return (
    <div>
      {isLoggedIn && <p>Welcome back!</p>}
    </div>
  );
};

export default MyComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

4.3. 立即执行函数表达式 (IIFE)

适用于需要执行更多逻辑或多条件判断的情况。

import React from 'react';

const MyComponent = () => {
  const status = 'loggedOut'; // 可以是 'loggedIn' 或 'loggedOut'

  return (
    <div>
      {(() => {
        if (status === 'loggedIn') {
          return <p>Welcome back!</p>;
        } else if (status === 'loggedOut') {
          return <p>Please sign in.</p>;
        } else {
          return <p>Status unknown.</p>;
        }
      })()}
    </div>
  );
};

export default MyComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

4.4 条件渲染组件

将条件渲染逻辑封装到单独的组件中,可以提高代码的可读性和复用性。

import React from 'react';

const Greeting = ({ isLoggedIn }) => {
  if (isLoggedIn) {
    return <p>Welcome back!</p>;
  } else {
    return <p>Please sign in.</p>;
  }
};

const MyComponent = () => {
  const isLoggedIn = true;

  return (
    <div>
      <Greeting isLoggedIn={isLoggedIn} />
    </div>
  );
};

export default MyComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

5.React基础事件绑定

5.1 基本事件绑定

在 React 中,可以直接在 JSX 中通过类似 HTML 的方式来绑定事件处理函数。例如,给按钮绑定点击事件:

import React from 'react';

const MyComponent = () => {
  const handleClick = () => {
    console.log('Button clicked!');
  };

  return (
    <div>
      <button onClick={handleClick}>Click me</button>
    </div>
  );
};

export default MyComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

在这个例子中,onClick 是 React 的事件属性,它接收一个函数作为值。当按钮被点击时,handleClick 函数会被调用。

5.2 事件处理函数

React 的事件处理函数与普通的 JavaScript 事件处理函数类似,它们接收一个合成事件对象 (SyntheticEvent),而不是原生 DOM 事件对象。这使得跨浏览器的事件处理更加一致和可靠。

import React from 'react';

const MyComponent = () => {
  const handleClick = (event) => {
    console.log('Button clicked!', event.target);
  };

  return (
    <div>
      <button onClick={handleClick}>Click me</button>
    </div>
  );
};

export default MyComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

在上面的示例中,handleClick 函数的参数 event 是一个合成事件对象,可以通过 event.target 访问触发事件的 DOM 元素。

5.3 事件传参

有时候需要给事件处理函数传递额外的参数。可以使用箭头函数或者 bind 方法来实现这一点。

使用箭头函数:

import React from 'react';

const MyComponent = () => {
  const handleClick = (name) => {
    console.log(`Hello, ${name} clicked!`);
  };

  return (
    <div>
      <button onClick={() => handleClick('World')}>Click me</button>
    </div>
  );
};

export default MyComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

使用 bind 方法:

import React from 'react';

const MyComponent = () => {
  const handleClick = (name) => {
    console.log(`Hello, ${name} clicked!`);
  };

  return (
    <div>
      <button onClick={handleClick.bind(null, 'World')}>Click me</button>
    </div>
  );
};

export default MyComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

这两种方式都可以将 'World' 作为参数传递给 handleClick 函数。

5.4 阻止事件默认行为和冒泡

在 React 中,阻止事件的默认行为和冒泡可以通过合成事件对象的方法来实现。

阻止默认行为:

import React from 'react';

const MyComponent = () => {
  const handleClick = (event) => {
    event.preventDefault();
    console.log('Button clicked!');
  };

  return (
    <div>
      <a href="#" onClick={handleClick}>Click me</a>
    </div>
  );
};

export default MyComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

阻止冒泡:

import React from 'react';

const MyComponent = () => {
  const handleClick = (event) => {
    event.stopPropagation();
    console.log('Button clicked!');
  };

  return (
    <div onClick={() => console.log('Div clicked!')}>
      <button onClick={handleClick}>Click me</button>
    </div>
  );
};

export default MyComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

总结

React 的事件绑定和处理与传统的 JavaScript 事件处理有些许差异,主要体现在事件对象的处理上,使用合成事件对象来实现跨浏览器一致性。通过上述方法,可以有效地在 React 中处理各种事件,并进行事件传参、阻止默认行为和冒泡等操作。

6.组件是什么?

在 React 中,组件是构建用户界面的基本单位,可以将 UI 分割成独立的、可复用的代码片段。组件可以是函数组件或类组件,它们可以接收输入的数据(称为 props)并返回描述页面展示内容的 React 元素。组件可以包含其他组件、HTML 标签和逻辑,使得复杂的 UI 可以被有效地管理和开发。

主要特点和作用:

  1. 封装和复用
    • 组件可以将 UI 划分成独立的部分,每个部分负责自己的功能,从而提高代码的可维护性和复用性。
  2. 组件层级
    • 组件可以嵌套组合,形成层次化的结构。父组件可以向子组件传递数据和函数,实现数据的流动和交互的功能。
  3. 状态管理
    • 类组件可以拥有状态(state),用于存储和管理组件内部的数据。状态的改变会触发组件的重新渲染,从而更新用户界面。
  4. 生命周期
    • 类组件具有生命周期方法,例如 componentDidMountcomponentDidUpdatecomponentWillUnmount 等,用于在组件生命周期不同阶段执行特定的逻辑。
  5. 纯UI组件和容器组件
    • 纯UI组件(Presentational Components)负责如何渲染数据,不涉及业务逻辑。容器组件(Container Components)则负责管理数据和状态,传递给纯UI组件。

示例:

以下是一个简单的 React 函数组件的示例,展示了一个名为 HelloWorld 的组件,它接收一个 name 属性作为输入,并渲染一个简单的问候语句:

import React from 'react';

// 函数组件:HelloWorld
const HelloWorld = ({ name }) => {
  return (
    <div>
      <h1>Hello, {name}!</h1>
      <p>Welcome to React components.</p>
    </div>
  );
};

export default HelloWorld;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

在这个例子中,HelloWorld 组件接收一个 name 属性,用于动态显示问候语。这种组件可以被多次使用,每次使用时传入不同的 name 属性,使得界面呈现的问候语可以个性化定制。

总之,React 组件是构建现代 Web 应用的核心概念之一,它们通过组合和抽象,使得开发者可以更加高效和灵活地构建用户界面。

7.useState使用介绍

useState 是 React 中的一个 Hook,用于在函数组件中添加状态管理功能。它允许你在函数组件中声明状态变量,并提供一个方法来更新这些状态。

使用方法

useState 是从 React 中导入的,并且通常在函数组件的顶部进行调用。它返回一个包含两个元素的数组:当前状态值和一个更新状态的函数。

基本示例

import React, { useState } from 'react';

const Counter = () => {
  // 声明一个名为 "count" 的状态变量,初始值为 0
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
};

export default Counter;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

在这个示例中:

  • const [count, setCount] = useState(0); 声明了一个名为 count 的状态变量,初始值为 0useState 返回一个数组,第一个元素是当前状态值(count),第二个元素是更新状态的函数(setCount)。
  • 每次点击按钮时,调用 setCount(count + 1) 更新 count 的值,从而触发组件的重新渲染,并更新显示的点击次数。

使用多个状态变量

你可以在一个组件中使用多个 useState 调用来管理不同的状态变量:

import React, { useState } from 'react';

const MultiStateComponent = () => {
  const [count, setCount] = useState(0);
  const [text, setText] = useState('');

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
      <input
        type="text"
        value={text}
        onChange={(e) => setText(e.target.value)}
        placeholder="Type something..."
      />
      <p>You typed: {text}</p>
    </div>
  );
};

export default MultiStateComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

在这个示例中,我们使用了两个 useState 调用来分别管理 counttext 两个状态变量。

初始化状态

你可以将状态的初始值设置为函数返回的值,这在初始化需要执行复杂计算时特别有用:

import React, { useState } from 'react';

const ExpensiveComponent = () => {
  const initialCount = () => {
    // 模拟一个复杂的计算
    return 42;
  };

  const [count, setCount] = useState(initialCount);

  return (
    <div>
      <p>Initial count: {count}</p>
      <button onClick={() => setCount(count + 1)}>
        Increment
      </button>
    </div>
  );
};

export default ExpensiveComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

在这个示例中,initialCount 函数只会在组件初次渲染时执行一次,用于计算初始状态值。

总结

  • useState 是一个 React Hook,用于在函数组件中添加状态管理功能。
  • useState 返回一个包含当前状态值和一个更新状态的函数的数组。
  • 可以使用多个 useState 调用来管理多个状态变量。
  • 状态的初始值可以是一个复杂计算的结果,通过传递一个函数来实现。

8.修改状态的规则

在 React 中,使用 useState 来管理和修改状态时,有一些规则和最佳实践需要遵循,以确保状态的管理和更新过程是高效和可靠的。以下是修改状态的主要规则和一些示例:

1. 状态更新是异步的

React 的状态更新是异步的,这意味着调用状态更新函数后,状态的更新不会立即反映出来,而是在下一次重新渲染时才会生效。

import React, { useState } from 'react';

const Counter = () => {
  const [count, setCount] = useState(0);

  const handleClick = () => {
    setCount(count + 1);
    console.log(count); // 这里的 count 可能不会立即更新
  };

  return (
    <div>
      <p>{count}</p>
      <button onClick={handleClick}>Increment</button>
    </div>
  );
};

export default Counter;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

在上述例子中,console.log(count) 可能不会立即显示更新后的值,因为状态更新是异步的。

2. 状态更新函数接受当前状态作为参数

为了确保状态更新时使用的值是最新的,可以传递一个函数给状态更新函数。这个函数会接收当前的状态值作为参数。

import React, { useState } from 'react';

const Counter = () => {
  const [count, setCount] = useState(0);

  const handleClick = () => {
    setCount(prevCount => prevCount + 1);
  };

  return (
    <div>
      <p>{count}</p>
      <button onClick={handleClick}>Increment</button>
    </div>
  );
};

export default Counter;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

在这个示例中,setCount 接收一个函数 prevCount => prevCount + 1,确保使用的是最新的状态值进行更新。

3. 不要直接修改状态

状态应该是不可变的,不要直接修改状态对象,而是通过创建新对象来更新状态。

import React, { useState } from 'react';

const Example = () => {
  const [user, setUser] = useState({ name: 'John', age: 30 });

  const updateAge = () => {
    setUser(prevUser => ({
      ...prevUser,
      age: prevUser.age + 1
    }));
  };

  return (
    <div>
      <p>{user.name}</p>
      <p>{user.age}</p>
      <button onClick={updateAge}>Increment Age</button>
    </div>
  );
};

export default Example;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

在这个示例中,使用扩展运算符 ...prevUser 创建了一个新的用户对象,并更新了年龄属性。

4. 合并状态

对于对象类型的状态,需要手动合并更新的部分,因为 useState 不会自动合并更新对象。

import React, { useState } from 'react';

const Example = () => {
  const [user, setUser] = useState({ name: 'John', age: 30 });

  const updateName = () => {
    setUser(prevUser => ({
      ...prevUser,
      name: 'Doe'
    }));
  };

  return (
    <div>
      <p>{user.name}</p>
      <p>{user.age}</p>
      <button onClick={updateName}>Update Name</button>
    </div>
  );
};

export default Example;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

在这个示例中,setUser 的更新函数创建了一个新的用户对象,同时保持其他属性不变。

5. 避免不必要的状态更新

尽量避免在每次渲染中都调用状态更新函数,只有在需要时才更新状态,以提高性能。

import React, { useState } from 'react';

const Example = () => {
  const [count, setCount] = useState(0);

  const handleClick = () => {
    if (count < 10) {
      setCount(count + 1);
    }
  };

  return (
    <div>
      <p>{count}</p>
      <button onClick={handleClick}>Increment</button>
    </div>
  );
};

export default Example;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

在这个示例中,只有在 count 小于 10 时才会更新状态,避免了不必要的状态更新。

总结

  1. 状态更新是异步的:不能依赖立即更新后的值。
  2. 使用函数式更新:在更新状态时,传递一个函数来确保使用最新的状态值。
  3. 不要直接修改状态:状态应该是不可变的,需要通过创建新对象来更新状态。
  4. 手动合并状态:对于对象类型的状态,需要手动合并更新部分。
  5. 避免不必要的状态更新:只有在需要时才更新状态,以提高性能。

9.基础样式方案

1.行内样式(不推荐):<div style={{color:“red”}}></>

2.class类名控制:

10.classNames优化类名控制

<div className={classNames(“foo”,{active:true})}>

</p> </div> ); }; export default MultiStateComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

Tässä esimerkissä käytämme kahta useState Soita hallitaksesi erikseencount jatext Kaksi tilamuuttujaa.

alustustila

Voit asettaa tilan alkuarvon funktion palauttamaan arvoon, mikä on erityisen hyödyllistä, kun alustus edellyttää monimutkaisten laskelmien suorittamista:

import React, { useState } from 'react';

const ExpensiveComponent = () => {
  const initialCount = () => {
    // 模拟一个复杂的计算
    return 42;
  };

  const [count, setCount] = useState(initialCount);

  return (
    <div>
      <p>Initial count: {count}</p>
      <button onClick={() => setCount(count + 1)}>
        Increment
      </button>
    </div>
  );
};

export default ExpensiveComponent;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

Tässä esimerkissäinitialCount Toiminto suoritetaan vain kerran, kun komponentti renderöidään ensimmäisen kerran alkutilan arvon laskemiseksi.

Tee yhteenveto

  • useState Onko React Hook, jota käytetään lisäämään tilanhallintatoimintoja toimintokomponentteihin.
  • useState Palauttaa taulukon, joka sisältää nykyisen tilan arvon ja toiminnon, joka päivittää tilan.
  • Voidaan käyttää useita useState Kutsutaan hallitsemaan useita tilamuuttujia.
  • Tilan alkuarvo voi olla monimutkaisen laskutoimituksen tulos, joka toteutetaan funktion välityksellä.

8. Säännöt tilan muuttamisesta

Käytä Reactissa useState Tilan hallinnassa ja muokkauksessa on joitain sääntöjä ja parhaita käytäntöjä, joita tulee noudattaa, jotta tilanhallinta- ja päivitysprosessi on tehokas ja luotettava. Tässä on tilan muokkaamisen pääsäännöt ja joitain esimerkkejä:

1. Tilapäivitykset ovat asynkronisia

Reactin tilapäivitykset ovat asynkronisia, mikä tarkoittaa, että tilanpäivitystoiminnon kutsumisen jälkeen tilapäivitykset eivät heijastu heti, vaan ne tulevat voimaan vasta seuraavan uudelleenrenderöinnin jälkeen.

import React, { useState } from 'react';

const Counter = () => {
  const [count, setCount] = useState(0);

  const handleClick = () => {
    setCount(count + 1);
    console.log(count); // 这里的 count 可能不会立即更新
  };

  return (
    <div>
      <p>{count}</p>
      <button onClick={handleClick}>Increment</button>
    </div>
  );
};

export default Counter;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

Yllä olevassa esimerkissäconsole.log(count) Päivitetty arvo ei välttämättä näy heti, koska tilapäivitykset ovat asynkronisia.

2. Tilan päivitystoiminto hyväksyy nykyisen tilan parametriksi

Varmistaaksesi, että tilan päivityksessä käytetyt arvot ovat uusimpia, voit siirtää toiminnon tilanpäivitystoimintoon. Tämä toiminto vastaanottaa nykyisen tilan arvon parametrina.

import React, { useState } from 'react';

const Counter = () => {
  const [count, setCount] = useState(0);

  const handleClick = () => {
    setCount(prevCount => prevCount + 1);
  };

  return (
    <div>
      <p>{count}</p>
      <button onClick={handleClick}>Increment</button>
    </div>
  );
};

export default Counter;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

Tässä esimerkissäsetCount saada toimintoprevCount => prevCount + 1, varmistaen, että päivityksessä käytetään viimeisintä tila-arvoa.

3. Älä muuta tilaa suoraan

Tilan tulee olla muuttumaton, älä muokkaa tilaobjektia suoraan, vaan päivitä tila luomalla uusia objekteja.

import React, { useState } from 'react';

const Example = () => {
  const [user, setUser] = useState({ name: 'John', age: 30 });

  const updateAge = () => {
    setUser(prevUser => ({
      ...prevUser,
      age: prevUser.age + 1
    }));
  };

  return (
    <div>
      <p>{user.name}</p>
      <p>{user.age}</p>
      <button onClick={updateAge}>Increment Age</button>
    </div>
  );
};

export default Example;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

Käytä tässä esimerkissä spread-operaattoria ...prevUser Uusi käyttäjäobjekti luodaan ja ikä-attribuutti päivitetään.

4. Yhdistämisen tila

Objektityyppitiloissa päivitetyt osat on yhdistettävä manuaalisesti, koska useState Päivitettyjä objekteja ei yhdistetä automaattisesti.

import React, { useState } from 'react';

const Example = () => {
  const [user, setUser] = useState({ name: 'John', age: 30 });

  const updateName = () => {
    setUser(prevUser => ({
      ...prevUser,
      name: 'Doe'
    }));
  };

  return (
    <div>
      <p>{user.name}</p>
      <p>{user.age}</p>
      <button onClick={updateName}>Update Name</button>
    </div>
  );
};

export default Example;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

Tässä esimerkissäsetUser Päivitystoiminto luo uuden käyttäjäobjektin jättäen muut ominaisuudet ennalleen.

5. Vältä tarpeettomia tilapäivityksiä

Yritä välttää tilanpäivitystoiminnon kutsumista jokaisessa renderöinnissa ja päivitä tila vain, kun se on tarpeen suorituskyvyn parantamiseksi.

import React, { useState } from 'react';

const Example = () => {
  const [count, setCount] = useState(0);

  const handleClick = () => {
    if (count < 10) {
      setCount(count + 1);
    }
  };

  return (
    <div>
      <p>{count}</p>
      <button onClick={handleClick}>Increment</button>
    </div>
  );
};

export default Example;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

Tässä esimerkissä vain jos count Tila päivitetään vain, kun arvo on alle 10, välttäen tarpeettomia tilapäivityksiä.

Tee yhteenveto

  1. Tilapäivitykset ovat asynkronisia: Ei voi luottaa välittömästi päivitettyihin arvoihin.
  2. Käytä toiminnallisia päivityksiä: Kun päivität tilaa, välitä funktio varmistaaksesi, että viimeisintä tila-arvoa käytetään.
  3. Älä muuta tilaa suoraan: Tilan tulee olla muuttumaton ja se on päivitettävä luomalla uusia objekteja.
  4. Manuaalinen yhdistämisen tila: Objektityyppien tilaa varten päivitysosa on yhdistettävä manuaalisesti.
  5. Vältä tarpeettomia tilapäivityksiä: Päivitä tila vain, kun sitä tarvitaan suorituskyvyn parantamiseksi.

9. Perustyylikaavio

1. Upotettu tyyli (ei suositella):{väri:"punainen"}}&gt;</>

2.class luokan nimen ohjaus:

10.classNames optimoi luokan nimenhallinnan

<div className={classNames(“foo”,{active:true})}>