技術共有

Reactの基礎学習-Day01

2024-07-12

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

Reactの基礎学習-Day01

1. React の概要

1.1 リアクションとは何ですか?

React は、Facebook によって開発および保守されている、ユーザー インターフェイスを構築するためのオープンソース JavaScript ライブラリです。 2013 年にオープンソース化されて以来、React はフロントエンド開発で人気の選択肢となり、シングルページ アプリケーション (SPA) や複雑なマルチページ アプリケーションの開発で広く使用されています。 React の主な目標は、UI 開発を簡素化し、より効率的で柔軟性があり、保守しやすいものにすることです。

1.2 React の利点は何ですか?

1.2.1 DOM と比較した React の利点
  1. 仮想 DOM と効率的なアップデート
    • 仮想 DOM : React は、仮想 DOM をメモリ内コピーとして使用して UI 構造を表現します。 Reactはデータが更新されるたびに、まず仮想DOM上で計算と比較を行い、変更部分を実際のDOMに一括更新します。この最適化により、DOM 操作が大幅に削減され、パフォーマンスが向上します。
    • 再描画とリフローを減らす: React は仮想 DOM を通じて、実際の DOM の頻繁な直接操作を回避し、ページの再描画 (リペイント) とリフロー (リフロー) を削減し、それによってページの応答速度とパフォーマンスを向上させることができます。
  2. コンポーネント化と再利用性
    • コンポーネント化 : React では、UI を独立したコンポーネントに分割し、各コンポーネントが独自の UI とロジックを担当することを推奨しています。このモジュール設計により、開発者はコードの再利用、テスト、保守が容易になります。
    • カスタムコンポーネント : 開発者はカスタム コンポーネントを作成し、これらのコンポーネントを組み合わせて複雑な UI を構築できます。この種の柔軟性と再利用性は、従来の DOM 操作では利用できません。
  3. 宣言型プログラミング スタイル
    • 宣言的な : React のプログラミング スタイルは宣言的です。開発者は UI がどのように見えるかを記述するだけでよく、更新のために DOM を操作する方法について心配する必要はありません。このアプローチはより直感的で理解しやすく、コードの保守性が向上します。
    • データ駆動型: React は、状態とプロパティ (props) を通じて UI を変更することを重視しています。データが変更されると、React が UI を更新するため、開発者は DOM を手動で操作する必要がありません。
  4. クロスプラットフォーム機能
    • リアクトネイティブ : Web アプリに加えて、React は同じコンポーネント モデルを使用したネイティブ モバイル アプリの構築もサポートしています。 React Native は、iOS および Android 上で高性能のネイティブ ユーザー インターフェイスを構築する方法を提供します。これにより、開発者はコードとスキルのほとんどを共有できるため、開発コストと学習曲線が削減されます。
  5. コミュニティとエコシステムのサポート
    • 巨大なコミュニティ: React には、開発者がアプリケーションをより効率的に開発およびデプロイできるよう、豊富なサードパーティ ライブラリ、ツール、ソリューションを提供する活発で大規模なコミュニティがあります。
    • コンポーネントライブラリ: 優れた UI コンポーネント ライブラリ (マテリアル UI、Ant Design など) や状態管理ツール (Redux、MobX など) が多数あり、React と組み合わせて使用​​することで、開発効率とアプリケーションをさらに向上させることができます。パフォーマンス。

要約すると、従来の DOM 操作と比較して、React は仮想 DOM、コンポーネント化、宣言型プログラミングなどの機能を通じて、より効率的で保守可能でスケーラブルな開発方法を提供します。これらの利点により、React はフロントエンド開発における主流のフレームワークの 1 つとなり、あらゆる規模や種類のプロジェクトで広く使用されています。

1.2.2 React と他のフレームワークの比較
  1. 柔軟性とカスタマイズ性
    • 反応する : React 自体は、完全なフレームワークではなくライブラリであり、ユーザー インターフェイスを構築するためのコア ツールとメカニズムを提供することに重点を置いています。開発者は、他のライブラリやツール (Redux、React Router など) を自由に選択して使用できます。それ。この柔軟性により、開発者はプロジェクトのニーズに基づいてより正確にカスタマイズおよび最適化することができます。
    • js の: Vue.js は、ルーティング、状態管理、ビルド ツールを含む、より包括的なソリューションを提供します。小規模から中規模のアプリケーション向けに、Vue.js はすぐに使用できる機能を提供し、統合と構成の複雑さを軽減します。 。
  2. 仮想DOMの実装
    • 反応する: React は一連の効率的な仮想 DOM および diff アルゴリズムを使用するため、大規模なデータ収集や頻繁なデータ更新の処理時に React のパフォーマンスが向上します。
    • js の: Vue.js も同様の仮想 DOM テクノロジーを使用していますが、一部のテストでは、特に複雑な UI 更新を処理する場合、React の差分アルゴリズムの方が高速である可能性があります。
  3. エコシステムとコミュニティのサポート
    • 反応する: React には、Redux、マテリアル UI などの豊富なサードパーティ ライブラリとツールをサポートする大規模で活発なコミュニティがあります。これらのライブラリは、開発者が複雑な単一ページ アプリケーションや大規模プロジェクトを構築するのに役立ちます。
    • js の: Vue.js コミュニティも非常に活発で、Vue.js エコシステムは、Vuex (状態管理)、Vue Router (ルーティング管理) などの多くのプラグインとツールを提供し、開発者により多くの選択肢と統合ソリューションを提供します。 。
  4. 学習曲線と使いやすさ
    • 反応する : React の学習曲線は比較的急勾配で、特に初心者にとっては、JSX、コンポーネントのライフサイクル、状態管理などの概念を習得する必要があります。ただし、React の中心的な概念をマスターすると、開発者は複雑なアプリケーションをより効率的に構築および保守できるようになります。
    • js の : Vue.js の学習曲線は比較的緩やかで、従来の HTML、CSS、JavaScript に近く、経験豊富な開発者と初心者の両方に優しいです。 Vue.js のドキュメントとチュートリアルも非常に包括的で、開発者がすぐに使い始めるのに役立ちます。
  5. コミュニティの文化と対応力
    • 反応する : React コミュニティはパフォーマンスと柔軟性により注意を払う傾向があり、TypeScript などのタイプ セーフなテクノロジ スタックを使用する傾向もあります。 React の主要なメンテナーとして、Facebook はセキュリティと安定性を高く保証しています。
    • js の : Vue.js コミュニティはよりオープンでフレンドリーで、開発者のエクスペリエンスと使いやすさに重点を置いています。 Vue.js は、既存のプロジェクトやライブラリとの統合など、他のテクノロジー スタックとの統合も容易です。

一般に、React と Vue.js はどちらも優れたフロントエンド開発フレームワークです。適切なフレームワークの選択は、プロジェクトの要件、チームのテクノロジー スタック、開発者の好みによって決まります。 React は、大規模で複雑なアプリケーション、特に高度な柔軟性とカスタマイズ性を必要とするシナリオに適している可能性があります。一方、Vue.js は、より統合された便利なソリューションを提供する、迅速な開発や中小規模のアプリケーションに適しています。

1.2.3 React は DOM と比較して再描画と再配置をどのように削減するか

リペイントとリフロー

  1. 再塗装: 要素の外観スタイル (色、背景、可視性など) が変更されても、レイアウトには影響しない場合、再描画がトリガーされます。
  2. リフロー : 要素のサイズ、位置、構造が変更されてレイアウトに影響を与えると、リフローがトリガーされます。リフローは、レイアウトとレンダー ツリーを再計算する必要があるため、再描画よりもコストがかかります。

React が再描画とリフローを減らす方法

  1. 仮想 DOM (仮想 DOM)
    • 仮想 DOM : React は、メモリ内に保持される UI の軽量コピーである仮想 DOM を作成します。コンポーネントの状態やプロパティが変化するたびに、React は仮想 DOM 内で計算と比較を実行して、新しい仮想 DOM ツリーを生成します。
    • 差分アルゴリズム: React は効率的な diff アルゴリズムを使用して、新旧の仮想 DOM ツリーを比較し、変更された部分を見つけて、更新パッチを生成します。
  2. 実際の DOM 操作を最小限に抑える
    • バッチアップデート : React は、複数のステータス更新を 1 つのバッチ更新に結合して、DOM 操作の数を減らします。バッチ更新では、複数の変更を一度に更新することで、頻繁な DOM 操作によって引き起こされるパフォーマンスの低下を回避します。
    • 非同期更新: React は、非同期バッチ処理 (React 18 で導入された同時モードなど) を使用して複数のステータス更新をマージし、頻繁な同期 DOM 操作を回避します。
  3. 不必要なアップデートを避ける
    • shouldComponentUpdate: クラスコンポーネント内で使用可能 shouldComponentUpdate 不必要な再描画やリフローを避けるためにコンポーネントを再レンダリングする必要があるかどうかを制御するメソッド。
    • リアクトメモ:関数コンポーネントが使用可能 React.memo パフォーマンスを最適化するために、前後のプロパティを比較し、プロパティが変更された場合にのみコンポーネントを再レンダリングします。
    • useMemo そしてuseCallback: フック提供 useMemo そしてuseCallback 計算結果と関数参照をキャッシュして、サブコンポーネントの不必要な更新を回避できます。
  4. 更新をマージする
    • ステータスのバッチ更新: React は複数のステータス更新を自動的にマージし、1 つのイベント ループで 1 つのレンダリングのみをトリガーするため、DOM 操作が軽減されます。

サンプルコード

次の例は、React がどのように渡すかを示しています。 React.memo そしてuseMemo 不必要なレンダリングを減らすには:

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

この例では:

  • ChildComponent でのみvalue 変更された場合にのみ再レンダリングされます。React.memo パック。
  • memoizedValue 使用useMemo 次の場合にのみキャッシュしますcount 変更された場合にのみ再計算されるため、不必要な計算やレンダリングが回避されます。

要約する

React は、仮想 DOM、バッチ更新、不要な更新の回避、更新のマージを通じて、再描画とリフローの数を効果的に削減し、それによってアプリケーションのパフォーマンスを向上させます。 DOM を直接操作する従来の方法と比較して、React はより効率的で最適化された UI 更新メカニズムを提供します。

2. jsx 構文の概要

.jsx はいJavaScript XML の略語で、開発者が HTML のようなマークアップ言語を JavaScript で直接記述して React コンポーネントの UI 構造を定義できるようにする JavaScript の構文拡張です。ここにあるいくつかの.jsx 文法の中心的な機能と使用法:

主な特徴:

  1. HTML のような構造
    • .jsx UI の構造とコンポーネントの外観を宣言するために、HTML に似たマークアップ言語を JavaScript に埋め込むことができます。
    • たとえば、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> このようなタグは、コンポーネントの UI 構造を構築するために JavaScript 関数で直接使用されます。
  • 使用 {name} 存在する<h1> 変数を動的に挿入するname 価値。
  • 使用 {} たとえば、中括弧で囲まれた JavaScript 式['apple', 'banana', 'cherry'].map() リスト項目を生成するには<li>
  • key={index} React でリスト項目を一意に識別するために使用され、React がコンポーネントの更新をより効率的に管理できるようにします。

予防:

  • JSX は本質的に JavaScript 構文の拡張です。Babel などのツールを使用してコンパイルし、標準の JavaScript コードに変換する必要があります。、ブラウザがそれを正しく解析して実行できるようにします。
  • JSX を使用すると、開発者は React コンポーネントの構造とロジックをより直観的に記述して理解できるようになり、コードの可読性と開発効率が向上します。

結論は、.jsx これは、コンポーネントの UI 構造を定義するために React で使用される構文拡張であり、JavaScript の表現力と HTML タグの直感性を組み合わせたもので、最新の Web アプリケーションを開発するための重要なツールの 1 つです。

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 三項演算子

これは、三項演算子を使用して単純な条件付きレンダリングを実装する最も一般的な方法です。

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. 論理積演算子

条件が true の場合にのみコンテンツが表示されるシナリオに適用されます。

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 では、イベント ハンドラーを HTML のような方法で JSX に直接バインドできます。たとえば、クリック イベントをボタンにバインドします。

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 イベント処理関数と似ており、ネイティブ DOM イベント オブジェクトの代わりに合成イベント オブジェクト (SyntheticEvent) を受け取ります。これにより、ブラウザー間でのイベント処理の一貫性と信頼性が向上します。

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. ステータス管理
    • クラス コンポーネントは状態を持つことができ、それはコンポーネント内でデータを保存および管理するために使用されます。状態が変化するとコンポーネントの再レンダリングがトリガーされ、ユーザー インターフェイスが更新されます。
  4. ライフサイクル
    • クラスコンポーネントには次のようなライフサイクルメソッドがあります。 componentDidMountcomponentDidUpdate そしてcomponentWillUnmount など、コンポーネントのライフサイクルのさまざまな段階で特定のロジックを実行するために使用されます。
  5. 純粋な UI コンポーネントとコンテナ コンポーネント
    • 純粋な UI コンポーネント (プレゼンテーション コンポーネント) はデータのレンダリング方法を担当し、ビジネス ロジックは関与しません。コンテナ コンポーネントは、データとステータスを管理し、それらを純粋な 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 アプリケーションを構築するための中心的な概念の 1 つであり、開発者は構成と抽象化を通じてユーザー インターフェイスをより効率的かつ柔軟に構築できます。

7.useStateの概要

useState これは React のフックであり、関数コンポーネントに状態管理機能を追加するために使用されます。これにより、機能コンポーネントで状態変数を宣言でき、これらの状態を更新するメソッドが提供されます。

説明書

useState React からインポートされ、通常は機能コンポーネントの先頭で呼び出されます。現在の状態値と状態を更新する関数の 2 つの要素を含む配列を返します。

基本的な例

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)、2 番目の要素は状態を更新する関数です (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=
                    
                        
                    
                    

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

この例では 2 つを使用します useState 個別に管理するための電話count そしてtext 2 つの状態変数。

初期化状態

状態の初期値を関数によって返される値に設定できます。これは、初期化で複雑な計算を実行する必要がある場合に特に便利です。

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 この関数は、初期状態値を計算するためにコンポーネントが最初にレンダリングされるときに 1 回だけ実行されます。

要約する

  • 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 update 関数は、他のプロパティを変更せずに新しいユーザー オブジェクトを作成します。

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. インライン スタイル (非推奨):{色:“赤”}}&gt;</>

2.class クラス名コントロール:

10.classNames はクラス名の制御を最適化します。

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