Κοινή χρήση τεχνολογίας

React basic learning-Day01

2024-07-12

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

React basic learning-Day01

1. Εισαγωγή στο React

1.1 Τι είναι το react;

Το React είναι μια βιβλιοθήκη JavaScript ανοιχτού κώδικα για τη δημιουργία διεπαφών χρήστη, που αναπτύχθηκε και διατηρείται από το Facebook. Από τότε που ήταν ανοιχτού κώδικα το 2013, το React έχει γίνει μια δημοφιλής επιλογή για ανάπτυξη front-end και χρησιμοποιείται ευρέως στην ανάπτυξη εφαρμογών μιας σελίδας (SPA) και σύνθετων πολυσέλιδων εφαρμογών. Ο κύριος στόχος του React είναι να απλοποιήσει την ανάπτυξη διεπαφής χρήστη και να την καταστήσει πιο αποτελεσματική, ευέλικτη και διατηρήσιμη.

1.2 Ποια είναι τα πλεονεκτήματα του react;

1.2.1 Τα πλεονεκτήματα του react σε σύγκριση με το DOM
  1. Εικονικό DOM και αποτελεσματικές ενημερώσεις
    • Εικονικό DOM : Το React χρησιμοποιεί ένα εικονικό DOM ως αντίγραφο στη μνήμη για την αναπαράσταση δομών διεπαφής χρήστη. Κάθε φορά που ενημερώνονται τα δεδομένα, το React εκτελεί πρώτα υπολογισμούς και συγκρίσεις στο εικονικό DOM και στη συνέχεια ενημερώνει τα αλλαγμένα μέρη στο πραγματικό DOM σε παρτίδες. Αυτή η βελτιστοποίηση μπορεί να μειώσει σημαντικά τις λειτουργίες DOM και να βελτιώσει την απόδοση.
    • Μειώστε τις επαναλήψεις και τις εκ νέου ροές: Μέσω του εικονικού DOM, το React μπορεί να αποφύγει τον συχνό άμεσο χειρισμό του πραγματικού DOM, να μειώσει τη ζωγραφική της σελίδας (επαναβάψιμο) και τη ροή (reflow), βελτιώνοντας έτσι την ταχύτητα απόκρισης και την απόδοση της σελίδας.
  2. Συστατικοποίηση και επαναχρησιμοποίηση
    • Συστατικοποίηση : Το React ενθαρρύνει τον διαχωρισμό της διεπαφής χρήστη σε ανεξάρτητα στοιχεία, με κάθε στοιχείο υπεύθυνο για τη δική του διεπαφή χρήστη και λογική. Αυτός ο αρθρωτός σχεδιασμός διευκολύνει τους προγραμματιστές να επαναχρησιμοποιήσουν, να δοκιμάσουν και να διατηρήσουν τον κώδικα.
    • Προσαρμοσμένο στοιχείο : Οι προγραμματιστές μπορούν να δημιουργήσουν προσαρμοσμένα στοιχεία και να δημιουργήσουν σύνθετες διεπαφές χρήστη συνδυάζοντας αυτά τα στοιχεία. Αυτό το είδος ευελιξίας και επαναχρησιμοποίησης δεν είναι διαθέσιμο στις παραδοσιακές λειτουργίες DOM.
  3. δηλωτικό στυλ προγραμματισμού
    • δηλωτικός : Το στυλ προγραμματισμού του React είναι δηλωτικό. Αυτή η προσέγγιση είναι πιο διαισθητική και πιο κατανοητή, βελτιώνοντας τη δυνατότητα συντήρησης του κώδικα.
    • δεδομένα: Το React δίνει έμφαση στην προώθηση αλλαγών διεπαφής χρήστη μέσω κατάστασης και ιδιοτήτων (props) Όταν αλλάζουν δεδομένα, το React είναι υπεύθυνο για την ενημέρωση της διεπαφής χρήστη και οι προγραμματιστές δεν χρειάζεται να χειρίζονται με μη αυτόματο τρόπο το DOM.
  4. Δυνατότητες πολλαπλών πλατφορμών
    • React Native : Εκτός από τις εφαρμογές ιστού, το React υποστηρίζει επίσης τη δημιουργία εγγενών εφαρμογών για κινητά χρησιμοποιώντας το ίδιο μοντέλο στοιχείων. Το React Native παρέχει έναν τρόπο δημιουργίας εγγενών διεπαφών χρήστη υψηλής απόδοσης σε iOS και Android, που επιτρέπει στους προγραμματιστές να μοιράζονται το μεγαλύτερο μέρος του κώδικα και τις δεξιότητές τους, μειώνοντας το κόστος ανάπτυξης και τις καμπύλες εκμάθησης.
  5. Υποστήριξη κοινότητας και οικοσυστήματος
    • τεράστια κοινότητα: Το React διαθέτει μια ενεργή και μεγάλη κοινότητα που παρέχει πληθώρα βιβλιοθηκών, εργαλείων και λύσεων τρίτων για να βοηθήσει τους προγραμματιστές να αναπτύξουν και να αναπτύξουν εφαρμογές πιο αποτελεσματικά.
    • Βιβλιοθήκη εξαρτημάτων: Υπάρχουν πολλές εξαιρετικές βιβλιοθήκες στοιχείων διεπαφής χρήστη (όπως Material-UI, Ant Design, κ.λπ.) και εργαλεία διαχείρισης κατάστασης (όπως Redux, MobX κ.λπ.) που μπορούν να χρησιμοποιηθούν σε συνδυασμό με το React για περαιτέρω βελτίωση της αποτελεσματικότητας ανάπτυξης και εφαρμογής εκτέλεση.

Συνοπτικά, σε σύγκριση με τις παραδοσιακές λειτουργίες DOM, το React παρέχει μια πιο αποτελεσματική, διατηρήσιμη και επεκτάσιμη μέθοδο ανάπτυξης μέσω λειτουργιών όπως το εικονικό DOM, η συνιστώσα και ο δηλωτικός προγραμματισμός. Αυτά τα πλεονεκτήματα καθιστούν το React ένα από τα κύρια πλαίσια ανάπτυξης front-end και χρησιμοποιείται ευρέως σε έργα όλων των μεγεθών και τύπων.

1.2.2 Σύγκριση μεταξύ react και άλλων πλαισίων
  1. Ευελιξία και δυνατότητα προσαρμογής
    • Αντιδρώ : Το React είναι μια βιβλιοθήκη και όχι ένα πλήρες πλαίσιο. Εστιάζει περισσότερο στην παροχή βασικών εργαλείων και μηχανισμών για τη δημιουργία διεπαφών χρήστη. το. Αυτή η ευελιξία επιτρέπει στους προγραμματιστές να προσαρμόζουν και να βελτιστοποιούν με μεγαλύτερη ακρίβεια με βάση τις ανάγκες του έργου.
    • Vue.js: Το Vue.js παρέχει μια πιο ολοκληρωμένη λύση, συμπεριλαμβανομένης της δρομολόγησης, της διαχείρισης κατάστασης και των εργαλείων κατασκευής. .
  2. Υλοποίηση εικονικού DOM
    • Αντιδρώ: Το React χρησιμοποιεί ένα σύνολο αποδοτικών εικονικών DOM και αλγορίθμων διαφορών, που κάνει το React να αποδίδει καλά κατά την επεξεργασία μεγάλων συλλογών δεδομένων και συχνών ενημερώσεων δεδομένων.
    • Vue.js: Το Vue.js χρησιμοποιεί επίσης παρόμοια εικονική τεχνολογία DOM, αλλά σε ορισμένες δοκιμές, ο αλγόριθμος διαφοράς του React μπορεί να είναι ταχύτερος, ειδικά όταν αντιμετωπίζετε πολύπλοκες ενημερώσεις διεπαφής χρήστη.
  3. Υποστήριξη οικοσυστήματος και κοινότητας
    • Αντιδρώ: Το React έχει μια μεγάλη και ενεργή κοινότητα που υποστηρίζει πληθώρα βιβλιοθηκών και εργαλείων τρίτων, όπως Redux, Material-UI, κ.λπ. Αυτές οι βιβλιοθήκες μπορούν να βοηθήσουν τους προγραμματιστές να δημιουργήσουν σύνθετες εφαρμογές μιας σελίδας και έργα μεγάλης κλίμακας.
    • Vue.js: Η κοινότητα Vue.js είναι επίσης πολύ ενεργή Το οικοσύστημα Vue.js παρέχει πολλά πρόσθετα και εργαλεία, όπως Vuex (διαχείριση κατάστασης), Vue Router (διαχείριση δρομολόγησης) κ.λπ., παρέχοντας στους προγραμματιστές περισσότερες επιλογές και λύσεις ενοποίησης. .
  4. Καμπύλη μάθησης και ευκολία χρήσης
    • Αντιδρώ : Η καμπύλη εκμάθησης του React είναι σχετικά απότομη, ειδικά για αρχάριους, που πρέπει να κυριαρχήσουν έννοιες όπως το JSX, ο κύκλος ζωής εξαρτημάτων και η διαχείριση κατάστασης. Αλλά μόλις κατακτήσετε τις βασικές έννοιες του React, οι προγραμματιστές μπορούν να δημιουργήσουν και να διατηρήσουν πολύπλοκες εφαρμογές πιο αποτελεσματικά.
    • Vue.js : Η καμπύλη εκμάθησης του Vue.js είναι σχετικά ήπια. Είναι πιο κοντά στο παραδοσιακό HTML, CSS και JavaScript και είναι φιλικό τόσο για έμπειρους προγραμματιστές όσο και για αρχάριους. Η τεκμηρίωση και τα σεμινάρια του Vue.js είναι επίσης πολύ ολοκληρωμένα, βοηθώντας τους προγραμματιστές να ξεκινήσουν γρήγορα.
  5. Κοινοτική κουλτούρα και ανταπόκριση
    • Αντιδρώ : Η κοινότητα του React τείνει να δίνει μεγαλύτερη προσοχή στην απόδοση και την ευελιξία και είναι επίσης πιο διατεθειμένη να χρησιμοποιεί στοίβες τεχνολογίας ασφαλούς τύπου, όπως το TypeScript. Ως κύριος συντηρητής του React, το Facebook έχει υψηλές εγγυήσεις για ασφάλεια και σταθερότητα.
    • Vue.js : Η κοινότητα του Vue.js είναι πιο ανοιχτή και φιλική, εστιάζοντας στην εμπειρία προγραμματιστή και στην ευκολία χρήσης. Το Vue.js είναι επίσης πιο εύκολο να ενσωματωθεί με άλλες στοίβες τεχνολογίας, όπως η ενσωμάτωση με υπάρχοντα έργα ή βιβλιοθήκες.

Σε γενικές γραμμές, το React και το Vue.js είναι και τα δύο εξαιρετικά πλαίσια ανάπτυξης front-end. Η επιλογή του κατάλληλου πλαισίου εξαρτάται από τις απαιτήσεις του έργου, τη στοίβα τεχνολογίας της ομάδας και τις προτιμήσεις προγραμματιστή. Το React μπορεί να είναι πιο κατάλληλο για μεγάλες και σύνθετες εφαρμογές, ειδικά σενάρια που απαιτούν υψηλό βαθμό ευελιξίας και δυνατότητας προσαρμογής, ενώ το Vue.js είναι πιο κατάλληλο για ταχεία ανάπτυξη και εφαρμογές μικρού και μεσαίου μεγέθους, παρέχοντας πιο ολοκληρωμένες και βολικές λύσεις.

1.2.3 Το How React μειώνει την επανασχεδίαση και την αναδιάταξη σε σύγκριση με το DOM

Repaint and Reflow

  1. Χρωματίζω πάλι: Όταν το στυλ εμφάνισης του στοιχείου (όπως χρώμα, φόντο, ορατότητα) αλλάζει, αλλά δεν επηρεάζει τη διάταξη, θα ενεργοποιηθεί μια νέα σχεδίαση.
  2. Reflow : Όταν το μέγεθος, η θέση ή η δομή ενός στοιχείου αλλάζει, επηρεάζοντας τη διάταξη, θα ενεργοποιηθεί η ανανέωση. Η ανανέωση είναι πιο ακριβή από την επανασχεδίαση, επειδή το δέντρο διάταξης και απόδοσης πρέπει να υπολογιστεί εκ νέου.

Το How React μειώνει τις επαναλήψεις και τις εκ νέου ροές

  1. Εικονικό DOM (Εικονικό DOM)
    • Εικονικό DOM : Το React δημιουργεί ένα εικονικό DOM, το οποίο είναι ένα ελαφρύ αντίγραφο του UI, που διατηρείται στη μνήμη. Κάθε φορά που αλλάζει η κατάσταση ή οι ιδιότητες ενός στοιχείου, το React θα εκτελεί υπολογισμούς και συγκρίσεις στο εικονικό DOM για να δημιουργήσει ένα νέο εικονικό δέντρο DOM.
    • Αλγόριθμος Diff: Το React χρησιμοποιεί έναν αποτελεσματικό αλγόριθμο διαφοράς για να συγκρίνει τα παλιά και νέα εικονικά δέντρα DOM, να βρει τα αλλαγμένα μέρη και να δημιουργήσει μια ενημέρωση κώδικα.
  2. Ελαχιστοποιήστε την πραγματική χειραγώγηση DOM
    • Ενημέρωση παρτίδας : Το React συνδυάζει πολλαπλές ενημερώσεις κατάστασης σε μία ομαδική ενημέρωση για να μειώσει τον αριθμό των λειτουργιών DOM. Η μαζική ενημέρωση αποφεύγει την απώλεια απόδοσης που προκαλείται από συχνές λειτουργίες DOM, ενημερώνοντας πολλές αλλαγές ταυτόχρονα.
    • Ασύγχρονες ενημερώσεις: Το React χρησιμοποιεί ασύγχρονη μαζική επεξεργασία (όπως η Ταυτόχρονη λειτουργία που εισήχθη στο React 18) για τη συγχώνευση πολλαπλών ενημερώσεων κατάστασης για την αποφυγή συχνών σύγχρονων λειτουργιών DOM.
  3. Αποφύγετε τις περιττές ενημερώσεις
    • shouldComponentUpdate: Μπορεί να χρησιμοποιηθεί σε εξαρτήματα κατηγορίας shouldComponentUpdate Μέθοδος για τον έλεγχο του εάν το στοιχείο πρέπει να αποδοθεί εκ νέου για να αποφευχθούν περιττές επανασχεδιάσεις και επαναλήψεις.
    • React.memo: Μπορούν να χρησιμοποιηθούν εξαρτήματα λειτουργίας React.memo Για βελτιστοποίηση απόδοσης, θα συγκρίνει τις ιδιότητες πριν και μετά και θα αποδώσει ξανά το στοιχείο μόνο όταν αλλάξουν οι ιδιότητες.
    • useMemo καιuseCallback: Παρέχεται από την Hooks useMemo καιuseCallback Τα αποτελέσματα των υπολογισμών και οι αναφορές συναρτήσεων μπορούν να αποθηκευτούν προσωρινά για να αποφευχθούν περιττές ενημερώσεις υποστοιχείων.
  4. Συγχώνευση ενημερώσεων
    • Ενημερώσεις κατάστασης παρτίδας: Το React θα συγχωνεύσει αυτόματα πολλές ενημερώσεις κατάστασης και θα ενεργοποιήσει μόνο μία απόδοση σε έναν βρόχο συμβάντος, μειώνοντας έτσι τις λειτουργίες 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 Θα επανυπολογιστεί μόνο όταν αλλάξει, αποφεύγοντας άσκοπους υπολογισμούς και απόδοση.

Συνοψίζω

Μέσω εικονικού DOM, μαζικών ενημερώσεων, αποφυγής περιττών ενημερώσεων και συγχωνεύσεων ενημερώσεων, το React μειώνει αποτελεσματικά τον αριθμό των επαναλήψεων και των ανανεώσεων, βελτιώνοντας έτσι την απόδοση της εφαρμογής. Σε σύγκριση με τον παραδοσιακό τρόπο απευθείας χειρισμού του DOM, το React παρέχει έναν πιο αποτελεσματικό και βελτιστοποιημένο μηχανισμό ενημέρωσης διεπαφής χρήστη.

2. Εισαγωγή στη σύνταξη jsx

.jsx ΝαίJavaScript XML Η συντομογραφία του , είναι μια επέκταση σύνταξης του JavaScript που επιτρέπει στους προγραμματιστές να γράφουν απευθείας γλώσσα σήμανσης παρόμοια με HTML σε JavaScript για να ορίσουν τη δομή διεπαφής χρήστη των στοιχείων React.Εδω είναι μερικά.jsx Τα βασικά χαρακτηριστικά και η χρήση της γραμματικής:

κύριο χαρακτηριστικό:

  1. Δομή που μοιάζει με HTML
    • .jsx Επιτρέπει την ενσωμάτωση μιας γλώσσας σήμανσης τύπου 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> Τέτοιες ετικέτες χρησιμοποιούνται απευθείας σε λειτουργίες JavaScript για τη δημιουργία της δομής διεπαφής χρήστη του στοιχείου.
  • χρήση {name} υπάρχει<h1> Εισαγάγετε δυναμικά μεταβλητέςname αξία.
  • χρήση {} Για παράδειγμα, εκφράσεις JavaScript τυλιγμένες σε σγουρά άγκιστρα['apple', 'banana', 'cherry'].map() για τη δημιουργία στοιχείων λίστας<li>
  • key={index} Χρησιμοποιείται για τον μοναδικό προσδιορισμό στοιχείων λίστας στο React, βοηθώντας το React να διαχειρίζεται τις ενημερώσεις στοιχείων πιο αποτελεσματικά.

Προφυλάξεις:

  • Το JSX είναι ουσιαστικά μια επέκταση της σύνταξης JavaScript.Πρέπει να μεταγλωττιστεί και να μετατραπεί σε τυπικό κώδικα JavaScript μέσω εργαλείων όπως το Babel., ώστε το πρόγραμμα περιήγησης να μπορεί να το αναλύσει και να το εκτελέσει σωστά.
  • Το JSX επιτρέπει στους προγραμματιστές να γράφουν και να κατανοούν τη δομή και τη λογική των στοιχείων του React πιο διαισθητικά, βελτιώνοντας την αναγνωσιμότητα κώδικα και την αποτελεσματικότητα ανάπτυξης.

Συμπερασματικά,.jsx Είναι μια επέκταση σύνταξης που χρησιμοποιείται στο React για τον καθορισμό της δομής διεπαφής χρήστη των στοιχείων. Συνδυάζει την εκφραστική ισχύ της JavaScript και τη διαισθητικότητά τους.

Το 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 Λογικός ΚΑΙ Χειριστής

Ισχύει για σενάρια όπου το περιεχόμενο αποδίδεται μόνο όταν η συνθήκη είναι αληθής.

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, τα στοιχεία είναι οι βασικές μονάδες για τη δημιουργία διεπαφών χρήστη και η διεπαφή χρήστη μπορεί να χωριστεί σεΑνεξάρτητα, επαναχρησιμοποιήσιμα αποσπάσματα κώδικα . Τα στοιχεία μπορεί να είναι στοιχεία συνάρτησης ή στοιχεία κλάσης που λαμβάνουν δεδομένα εισόδου (που ονομάζονται props) και επιστρέφουν στοιχεία React που περιγράφουν το περιεχόμενο που εμφανίζεται στη σελίδα. Τα στοιχεία μπορούν να περιέχουν άλλα στοιχεία, ετικέτες HTML και λογική, έτσι ώστε οι σύνθετες διεπαφές να μπορούν να διαχειρίζονται και να αναπτύσσονται αποτελεσματικά.

Κύρια χαρακτηριστικά και λειτουργίες:

  1. Ενθυλάκωση και επαναχρησιμοποίηση
    • Τα στοιχεία μπορούν να χωρίσουν τη διεπαφή χρήστη σε ανεξάρτητα μέρη, κάθε τμήμα είναι υπεύθυνο για τη δική του λειτουργία, βελτιώνοντας έτσι τη δυνατότητα συντήρησης και επαναχρησιμοποίησης του κώδικα.
  2. ιεραρχία συστατικών
    • Τα εξαρτήματα μπορούν να ενσωματωθούν και να συνδυαστούν για να σχηματίσουν μια ιεραρχική δομή. Τα γονικά στοιχεία μπορούν να περάσουν δεδομένα και συναρτήσεις σε θυγατρικά στοιχεία για να πραγματοποιήσουν τις λειτουργίες ροής δεδομένων και αλληλεπίδρασης.
  3. Διαχείριση κατάστασης
    • Τα στοιχεία κλάσης μπορούν να έχουν κατάσταση, η οποία χρησιμοποιείται για την αποθήκευση και τη διαχείριση δεδομένων εντός του στοιχείου. Αλλαγές στην κατάσταση ενεργοποιούν μια εκ νέου απόδοση του στοιχείου, ενημερώνοντας έτσι τη διεπαφή χρήστη.
  4. κύκλος ζωής
    • Τα στοιχεία της κλάσης έχουν μεθόδους κύκλου ζωής όπως π.χ componentDidMountcomponentDidUpdate καιcomponentWillUnmount κ.λπ., που χρησιμοποιείται για την εκτέλεση συγκεκριμένης λογικής σε διαφορετικά στάδια του κύκλου ζωής του εξαρτήματος.
  5. Καθαρά στοιχεία διεπαφής χρήστη και εξαρτήματα κοντέινερ
    • Τα καθαρά στοιχεία διεπαφής χρήστη (Presentational Components) είναι υπεύθυνα για τον τρόπο απόδοσης των δεδομένων και δεν περιλαμβάνουν επιχειρηματική λογική. Τα Container Components είναι υπεύθυνα για τη διαχείριση των δεδομένων και της κατάστασης και τη διαβίβασή τους σε καθαρά στοιχεία διεπαφής χρήστη.

Παράδειγμα:

Ακολουθεί ένα παράδειγμα ενός απλού στοιχείου συνάρτησης 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 είναι μία από τις βασικές έννοιες για τη δημιουργία σύγχρονων εφαρμογών Ιστού Μέσω της σύνθεσης και της αφαίρεσης, επιτρέπουν στους προγραμματιστές να δημιουργούν διεπαφές χρήστη πιο αποτελεσματικά και ευέλικτα.

7.Εισαγωγή στη χρήσηState

useState Είναι ένα Hook in React, που χρησιμοποιείται για την προσθήκη λειτουργιών διαχείρισης κατάστασης σε στοιχεία λειτουργιών. Σας επιτρέπει να δηλώνετε μεταβλητές κατάστασης σε λειτουργικά στοιχεία και παρέχει μια μέθοδο ενημέρωσης αυτών των καταστάσεων.

Οδηγίες

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=
                    
                        
                    
                    

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

Σε αυτό το παράδειγμα χρησιμοποιούμε δύο useState Καλέστε για διαχείριση ξεχωριστάcount καιtext Δύο μεταβλητές κατάστασης.

κατάσταση αρχικοποίησης

Μπορείτε να ορίσετε την αρχική τιμή της κατάστασης στην τιμή που επιστρέφεται από τη συνάρτηση, η οποία είναι ιδιαίτερα χρήσιμη όταν η προετοιμασία απαιτεί την εκτέλεση πολύπλοκων υπολογισμών:

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

Σε αυτό το παράδειγμα, χρησιμοποιήστε τον τελεστή spread ...prevUser Δημιουργείται ένα νέο αντικείμενο χρήστη και ενημερώνεται το χαρακτηριστικό age.

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. Ενσωματωμένο στυλ (δεν συνιστάται):{color:"κόκκινο"}}&gt;</>

Έλεγχος ονόματος κλάσης 2.class:

10.classNames βελτιστοποιεί τον έλεγχο ονόματος κλάσης

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