기술나눔

리액트 기본학습-Day01

2024-07-12

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

리액트 기본학습-Day01

1. 리액트 소개

1.1 반응이란 무엇입니까?

React는 Facebook에서 개발하고 유지 관리하는 사용자 인터페이스 구축을 위한 오픈 소스 JavaScript 라이브러리입니다. 2013년에 오픈 소스로 공개된 이후 React는 프런트 엔드 개발에 널리 사용되며 단일 페이지 애플리케이션(SPA) 및 복잡한 다중 페이지 애플리케이션 개발에 널리 사용됩니다. React의 주요 목표는 UI 개발을 단순화하고 이를 보다 효율적이고 유연하며 유지 관리 가능하게 만드는 것입니다.

1.2 반응의 장점은 무엇입니까?

1.2.1 DOM과 비교한 React의 장점
  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는 상태와 속성(props)을 통해 UI 변경을 유도하는 것을 강조합니다. 데이터가 변경되면 React가 UI 업데이트를 담당하므로 개발자가 수동으로 DOM을 조작할 필요가 없습니다.
  4. 크로스 플랫폼 기능
    • 리액트 네이티브 : React는 웹 앱 외에도 동일한 구성 요소 모델을 사용하여 기본 모바일 앱 구축을 지원합니다. React Native는 iOS 및 Android에서 고성능 네이티브 사용자 인터페이스를 구축하는 방법을 제공하므로 개발자는 대부분의 코드와 기술을 공유하여 개발 비용과 학습 곡선을 줄일 수 있습니다.
  5. 커뮤니티 및 생태계 지원
    • 거대한 커뮤니티: React에는 개발자가 애플리케이션을 보다 효율적으로 개발하고 배포하는 데 도움이 되는 풍부한 타사 라이브러리, 도구 및 솔루션을 제공하는 활발하고 대규모 커뮤니티가 있습니다.
    • 구성 요소 라이브러리: 개발 효율성과 응용성을 더욱 향상시키기 위해 React와 함께 사용할 수 있는 우수한 UI 구성 요소 라이브러리(예: Material-UI, Ant Design 등)와 상태 관리 도구(예: Redux, MobX 등)가 많이 있습니다. 성능.

요약하자면, 기존 DOM 작업과 비교하여 React는 가상 DOM, 구성 요소화 및 선언적 프로그래밍과 같은 기능을 통해 보다 효율적이고 유지 관리 및 확장 가능한 개발 방법을 제공합니다. 이러한 장점으로 인해 React는 프런트엔드 개발의 주류 프레임워크 중 하나가 되었으며 모든 규모와 유형의 프로젝트에서 널리 사용됩니다.

1.2.2 React와 다른 프레임워크의 비교
  1. 유연성과 맞춤화 가능성
    • 반응하다 : React 자체는 완전한 프레임워크라기보다는 사용자 인터페이스 구축을 위한 핵심 도구와 메커니즘을 제공하는 데 더 중점을 둡니다. 개발자는 Redux, React Router 등의 다른 라이브러리와 도구를 자유롭게 선택할 수 있습니다. 그것. 이러한 유연성을 통해 개발자는 프로젝트 요구 사항에 따라 보다 정확하게 사용자 정의하고 최적화할 수 있습니다.
    • 뷰.js: Vue.js는 라우팅, 상태 관리 및 빌드 도구를 포함하여 보다 포괄적인 솔루션을 제공합니다. 중소 규모 애플리케이션의 경우 Vue.js는 더 많은 기본 기능을 제공하고 통합 및 구성의 복잡성을 줄입니다. .
  2. 가상 DOM 구현
    • 반응하다: React는 효율적인 가상 DOM 및 diff 알고리즘 세트를 사용하므로 대규모 데이터 수집 및 빈번한 데이터 업데이트를 처리할 때 React의 성능이 향상됩니다.
    • 뷰.js: Vue.js도 유사한 가상 DOM 기술을 사용하지만 일부 테스트에서는 특히 복잡한 UI 업데이트를 처리할 때 React의 diff 알고리즘이 더 빠를 수 있습니다.
  3. 생태계 및 커뮤니티 지원
    • 반응하다: React에는 Redux, Material-UI 등과 같은 풍부한 타사 라이브러리 및 도구를 지원하는 크고 활동적인 커뮤니티가 있습니다. 이러한 라이브러리는 개발자가 복잡한 단일 페이지 애플리케이션 및 대규모 프로젝트를 구축하는 데 도움이 될 수 있습니다.
    • 뷰.js: Vue.js 커뮤니티도 매우 활발합니다. Vue.js 생태계는 Vuex(상태 관리), Vue Router(라우팅 관리) 등과 같은 많은 플러그인과 도구를 제공하여 개발자에게 더 많은 선택권과 통합 솔루션을 제공합니다. .
  4. 학습 곡선 및 사용 용이성
    • 반응하다 : React의 학습 곡선은 상대적으로 가파르며, 특히 JSX, 구성 요소 수명 주기, 상태 관리와 같은 개념을 숙달해야 하는 초보자의 경우 더욱 그렇습니다. 그러나 일단 React의 핵심 개념을 익히면 개발자는 복잡한 애플리케이션을 보다 효율적으로 구축하고 유지할 수 있습니다.
    • 뷰.js : Vue.js의 학습 곡선은 상대적으로 완만하며 전통적인 HTML, CSS 및 JavaScript에 더 가깝고 숙련된 개발자와 초보자 모두에게 친숙합니다. Vue.js의 문서와 튜토리얼도 매우 포괄적이어서 개발자가 빠르게 시작할 수 있도록 도와줍니다.
  5. 커뮤니티 문화 및 대응
    • 반응하다 : React 커뮤니티는 성능과 유연성에 더 많은 관심을 기울이는 경향이 있으며 TypeScript와 같은 유형이 안전한 기술 스택을 사용하는 경향이 있습니다. React의 주요 관리자로서 Facebook은 보안과 안정성에 대해 높은 수준의 보장을 갖고 있습니다.
    • 뷰.js : Vue.js 커뮤니티는 개발자 경험과 사용 편의성에 중점을 두고 더욱 개방적이고 친근합니다. Vue.js는 기존 프로젝트나 라이브러리와의 통합과 같은 다른 기술 스택과의 통합도 더 쉽습니다.

일반적으로 React와 Vue.js는 모두 뛰어난 프런트 엔드 개발 프레임워크입니다. 적절한 프레임워크를 선택하는 것은 프로젝트 요구 사항, 팀 기술 스택 및 개발자 선호도에 따라 다릅니다. React는 크고 복잡한 애플리케이션, 특히 높은 수준의 유연성과 사용자 정의 가능성이 필요한 시나리오에 더 적합할 수 있으며, Vue.js는 빠른 개발 및 중소 규모 애플리케이션에 더 적합하여 보다 통합되고 편리한 솔루션을 제공합니다.

1.2.3 React가 DOM에 비해 다시 그리기와 재배열을 줄이는 방법

다시 그리기 및 리플로우

  1. 다시 칠하기: 요소의 모양 스타일(예: 색상, 배경, 가시성)이 변경되지만 레이아웃에 영향을 주지 않으면 다시 그리기가 트리거됩니다.
  2. 리플로우 : 요소의 크기, 위치 또는 구조가 변경되어 레이아웃에 영향을 미치는 경우 리플로우가 트리거됩니다. 리플로우는 레이아웃과 렌더 트리를 다시 계산해야 하기 때문에 다시 그리는 것보다 비용이 더 많이 듭니다.

React가 다시 그리기와 리플로우를 줄이는 방법

  1. 가상 DOM(가상 DOM)
    • 가상 DOM : React는 메모리에 보관되는 UI의 경량 복사본인 가상 DOM을 생성합니다. 구성 요소의 상태나 속성이 변경될 때마다 React는 가상 DOM에서 계산과 비교를 수행하여 새로운 가상 DOM 트리를 생성합니다.
    • 비교 알고리즘: React는 효율적인 diff 알고리즘을 사용하여 이전 가상 DOM 트리와 새 가상 DOM 트리를 비교하고 변경된 부분을 찾아 업데이트 패치를 생성합니다.
  2. 실제 DOM 조작 최소화
    • 일괄 업데이트 : React는 여러 상태 업데이트를 하나의 일괄 업데이트로 결합하여 DOM 작업 수를 줄입니다. 일괄 업데이트는 여러 변경 사항을 한 번에 업데이트하여 빈번한 DOM 작업으로 인한 성능 손실을 방지합니다.
    • 비동기 업데이트: React는 비동기 일괄 처리(예: React 18에 도입된 동시 모드)를 사용하여 여러 상태 업데이트를 병합하여 빈번한 동기 DOM 작업을 방지합니다.
  3. 불필요한 업데이트 방지
    • shouldComponentUpdate: 클래스 컴포넌트에서 사용 가능 shouldComponentUpdate 불필요한 다시 그리기 및 리플로우를 피하기 위해 구성 요소를 다시 렌더링해야 하는지 여부를 제어하는 ​​방법입니다.
    • 리액트.메모: 기능 컴포넌트를 사용할 수 있습니다. 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는 보다 효율적이고 최적화된 UI 업데이트 메커니즘을 제공합니다.

2. jsx 구문 소개

.jsx자바스크립트 XML 의 약자로, 개발자가 HTML과 유사한 마크업 언어를 JavaScript로 직접 작성하여 React 구성 요소의 UI 구조를 정의할 수 있도록 하는 JavaScript의 구문 확장입니다.다음은 일부입니다..jsx 문법의 핵심 기능과 사용법:

주요 특징:

  1. HTML과 유사한 구조
    • .jsx UI 구조와 구성 요소의 모양을 선언하기 위해 HTML과 유사한 마크업 언어를 JavaScript에 포함할 수 있습니다.
    • 예를 들어 React에서는 직접 사용할 수 있습니다. <div><span><h1> HTML 태그 및 사용자 정의 React 구성 요소.
  2. JSX 표현
    • 존재하다 .jsx 에서 사용할 수 있습니다{} 중괄호는 JavaScript 표현식을 래핑하는 데 사용되며 변수, 계산 결과 또는 함수 호출을 마크업에 동적으로 삽입하는 데 사용됩니다.
    • 이것은 만든다 .jsx JavaScript의 모든 표현 기능을 갖추고 있으며 조건부 판단, 반복, 계산 등의 작업을 수행할 수 있습니다.
  3. 재산 양도
    • HTML과 유사하며,.jsx 라벨의 속성 사용을 허용하고 속성 값으로 표현식을 지원합니다.
    • 예를 들어:<Component name={variable} />,안에 name 속성입니다.variable JavaScript 변수 또는 표현식입니다.
  4. 자동 폐쇄 라벨
    • .jsx 의 라벨은 다음과 같이 자동으로 닫힐 수 있습니다.<img><input>, 당신은 또한 사용할 수 있습니다 / 자체 폐쇄를 나타내는 기호(예: )<br />
  5. 논평
    • JavaScript와 마찬가지로 다음을 사용할 수 있습니다. // 한줄 주석과/* */ 여러 줄 주석.jsx 파일에 주석 추가(댓글은 {} 내에 작성되어야 합니다.)。

예:

다음은 간단한 React 구성 요소 예입니다. .jsx 기본 구문 및 기능:

import React from 'react';

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

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

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

이 예에서는 다음과 같습니다.

  • <h1><p><ul> 그리고<li> 이러한 태그는 구성 요소의 UI 구조를 구축하기 위해 JavaScript 함수에서 직접 사용됩니다.
  • 사용 {name} 존재하다<h1> 변수를 동적으로 삽입name 값.
  • 사용 {} 예를 들어 중괄호로 묶인 JavaScript 표현식['apple', 'banana', 'cherry'].map() 목록 항목을 생성하려면<li>
  • key={index} React에서 목록 항목을 고유하게 식별하는 데 사용되어 React가 구성 요소 업데이트를 보다 효율적으로 관리하는 데 도움이 됩니다.

지침:

  • JSX는 기본적으로 JavaScript 구문의 확장입니다.Babel과 같은 도구를 통해 컴파일하고 표준 JavaScript 코드로 변환해야 합니다., 브라우저가 이를 올바르게 구문 분석하고 실행할 수 있도록 합니다.
  • JSX를 사용하면 개발자는 React 구성 요소의 구조와 논리를 보다 직관적으로 작성하고 이해할 수 있어 코드 가독성과 개발 효율성이 향상됩니다.

결론적으로,.jsx React에서 컴포넌트의 UI 구조를 정의하는 데 사용되는 구문 확장으로, JavaScript의 표현력과 HTML 태그의 직관성을 결합한 것입니다.

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. 논리 AND 연산자

조건이 true인 경우에만 콘텐츠가 렌더링되는 시나리오에 적용 가능합니다.

import React from 'react';

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

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

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

4.3 함수 표현식 즉시 실행(IIFE)

더 많은 논리 또는 다중 조건 판단을 수행해야 하는 상황에 적합합니다.

import React from 'react';

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

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

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

4.4 조건부 렌더링 구성 요소

조건부 렌더링 논리를 별도의 구성 요소로 캡슐화하면 코드 가독성과 재사용성이 향상될 수 있습니다.

import React from 'react';

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

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

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

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

5.React 기본 이벤트 바인딩

5.1 기본 이벤트 바인딩

React에서 이벤트 핸들러는 HTML과 같은 방식으로 JSX에 직접 바인딩될 수 있습니다. 예를 들어 클릭 이벤트를 버튼에 바인딩합니다.

import React from 'react';

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

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

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

이 예에서는onClick 함수를 값으로 전달받는 React의 이벤트 속성입니다. 버튼을 클릭하면,handleClick 함수가 호출됩니다.

5.2 이벤트 처리 기능

React의 이벤트 처리 함수는 일반 JavaScript 이벤트 처리 함수와 유사하며 기본 DOM 이벤트 객체 대신 합성 이벤트 객체(SyntheticEvent)를 받습니다. 이를 통해 브라우저 전반에서 이벤트 처리가 더욱 일관되고 안정적으로 이루어집니다.

import React from 'react';

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

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

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

위의 예에서,handleClick 함수 매개변수event 전달할 수 있는 합성 이벤트 객체입니다.event.target 이벤트를 트리거한 DOM 요소에 액세스합니다.

5.3 이벤트 매개변수 전달

때로는 이벤트 핸들러 함수에 추가 매개변수를 전달해야 하는 경우도 있습니다.화살표 기능을 사용하거나bind 이를 달성하는 방법.

화살표 기능을 사용하세요:

import React from 'react';

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

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

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

사용 bind 방법:

import React from 'react';

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

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

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

이 두 가지 방법 모두 가능합니다. 'World' 매개변수로 전달됨handleClick 기능.

5.4 이벤트 기본 동작 및 버블링 방지

React에서는 합성 이벤트 객체의 메서드를 통해 이벤트의 기본 동작과 버블링을 방지할 수 있습니다.

기본 동작 방지:

import React from 'react';

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

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

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

버블링을 중지합니다.

import React from 'react';

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

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

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

요약하다

React의 이벤트 바인딩 및 처리는 전통적인 JavaScript 이벤트 처리와 약간 다릅니다. 주로 이벤트 개체 처리에 반영되며 합성 이벤트 개체를 사용하여 브라우저 간 일관성을 달성합니다. 위의 방법을 통해 React에서 다양한 이벤트를 효과적으로 처리할 수 있으며, 이벤트 매개변수 전달, 기본 동작 방지, 버블링 등의 작업을 수행할 수 있습니다.

6. 구성요소란 무엇입니까?

React에서 컴포넌트는 사용자 인터페이스를 구축하기 위한 기본 단위이며, UI는 다음과 같이 나눌 수 있습니다.독립적이고 재사용 가능한 코드 조각 . 구성 요소는 입력 데이터(props라고 함)를 수신하고 페이지에 표시되는 콘텐츠를 설명하는 React 요소를 반환하는 함수 구성 요소 또는 클래스 구성 요소일 수 있습니다. 구성 요소에는 복잡한 UI를 효율적으로 관리하고 개발할 수 있도록 다른 구성 요소, HTML 태그 및 논리가 포함될 수 있습니다.

주요 특징 및 기능:

  1. 캡슐화 및 재사용
    • 구성 요소는 UI를 독립적인 부분으로 나눌 수 있으며, 각 부분은 자체 기능을 담당하므로 코드의 유지 관리성과 재사용성이 향상됩니다.
  2. 구성 요소 계층 구조
    • 구성 요소를 중첩하고 결합하여 계층 구조를 형성할 수 있습니다. 상위 구성 요소는 데이터 흐름과 상호 작용 기능을 실현하기 위해 데이터와 기능을 하위 구성 요소에 전달할 수 있습니다.
  3. 현황관리
    • 클래스 구성 요소는 구성 요소 내에서 데이터를 저장하고 관리하는 데 사용되는 상태를 가질 수 있습니다. 상태가 변경되면 구성 요소가 다시 렌더링되어 사용자 인터페이스가 업데이트됩니다.
  4. 수명주기
    • 클래스 구성 요소에는 다음과 같은 수명 주기 메서드가 있습니다. componentDidMountcomponentDidUpdate 그리고componentWillUnmount 등, 구성 요소 수명주기의 여러 단계에서 특정 논리를 실행하는 데 사용됩니다.
  5. 순수 UI 구성 요소 및 컨테이너 구성 요소
    • 순수 UI 구성 요소(프레젠테이션 구성 요소)는 데이터 렌더링 방법을 담당하며 비즈니스 논리를 포함하지 않습니다. 컨테이너 구성 요소는 데이터와 상태를 관리하고 이를 순수 UI 구성 요소에 전달하는 역할을 담당합니다.

예:

다음은 간단한 React 함수 구성 요소의 예입니다. HelloWorld 수신하는 구성 요소name 속성을 입력으로 사용하고 간단한 인사말을 렌더링합니다.

import React from 'react';

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

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

이 예에서는HelloWorld 구성요소는name 인사말을 동적으로 표시하기 위한 속성입니다.이 구성 요소는 여러 번 사용될 수 있으며 사용될 때마다 다른 값을 전달합니다.name 속성을 사용하면 인터페이스에 표시되는 인사말을 사용자 정의할 수 있습니다.

간단히 말해서, React 구성요소는 현대적인 웹 애플리케이션을 구축하기 위한 핵심 개념 중 하나이며, 구성과 추상화를 통해 개발자는 보다 효율적이고 유연하게 사용자 인터페이스를 구축할 수 있습니다.

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=
                    
                        
                    
                    

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. 상태 수정 규칙

반응에서 사용 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. 인라인 스타일(권장하지 않음):{color:“빨간색”}}&gt;</>

2.클래스 클래스 이름 제어:

10.classNames는 클래스 이름 제어를 최적화합니다.

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