React(涉及基础和Usestate)

发布时间 2023-08-15 10:12:46作者: Calvin-Zhao

React

React是JavaScript的一个类库;

Rendering User Interfaces

React

To understand how React works, we first need a basic understanding of how browsers interpret your code to create interactive user interfaces (UI).

浏览器构建用户界面原理

When a user visits a web page, the server returns an HTML file to the browser that may look like this:

image-20230812153411143

The browser then reads the HTML and constructs the Document Object Model (DOM).

What is the DOM?

The DOM is an object representation of the HTML elements. It acts as a bridge between your code and the user interface, and has a tree-like structure with parent and child relationships.

img

You can use DOM methods and a programming language, such as JavaScript, to listen to user events and manipulate the DOM by selecting, adding, updating, and deleting specific elements in the user interface. DOM manipulation allows you to not only target specific elements, but also change their style and content.

DOM是一种Html元素的对象表示形式。使用DOM方法和编程语言JavaScript可以改变DOM;

Component

In React, components are functions.

How Next.js Works

What is Bundling?

Developers break up their application into modules, components, and functions that can be used to build larger pieces of their application. Exporting and importing these internal modules, as well as external third-party packages, creates a complex web of file dependencies.

img

Bundling is the process of resolving the web of dependencies and merging (or ‘packaging’) the files (or modules) into optimized bundles for the browser, with the goal of reducing the number of requests for files when a user visits a web page.

Bundling:打包是将许多文件打包成更少的文件,使用户一次请求可以拿到更多的数据,减少用户请求次数;

Compile:编译是将代码编译成浏览器看得到的形式;

What is Code Splitting?

Developers usually split their applications into multiple pages that can be accessed from different URLs. Each of these pages becomes a unique entry point into the application.

Code-splitting is the process of splitting the application’s bundle into smaller chunks required by each entry point. The goal is to improve the application's initial load time by only loading the code required to run that page.

img

代码分割

Next.js has built-in support for code splitting. Each file inside your pages/ directory will be automatically code split into its own JavaScript bundle during the build step.

Further:

  • Any code shared between pages is also split into another bundle to avoid re-downloading the same code on further navigation.
  • After the initial page load, Next.js can start [pre-loading the code](https://nextjs.org/docs/api-reference/next/link#:~:text=Defaults to false-,prefetch,-- Prefetch the page) of other pages users are likely to navigate to.
  • Dynamic imports are another way to manually split what code is initially loaded.
EXAMPLE
import { useState, useEffect } from 'react';

// 首页组件
const Home = () => {
  const [data, setData] = useState(null);

  useEffect(() => {
    // 延迟加载数据模块
    import('../modules/data').then(module => {
      const fetchData = module.default;
      fetchData().then(result => {
        setData(result);
      });
    });
  }, []);

  return (
    <div>
      <h1>首页</h1>
      {data && <p>{data}</p>}
    </div>
  );
};

export default Home;

使用了动态导入语法来延迟加载名为 data 的模块。当用户访问首页时,才会开始下载和执行该模块的 JavaScript 代码。

这样可以实现按需加载数据模块,提高初始页面加载速度并减小初始加载的 JavaScript 包大小。

具体流程示例

用户点击一个网页,那么最好的方式是将这个页面用到的文件(数据)发给用户。(这是就要用到代码分割)

Next.js会将page目录下的文件自动分割进它自己的JS包;(意思是如果你访问首页,那么他就将首页的包发给你)

代码分割和打包息息相关:分割完之后,打成包;

What is Rendering?

There is an unavoidable unit of work to convert the code you write in React into the HTML representation of your UI. This process is called rendering.

Type of Rendering

Pre-Rendering/Static Generation/Client-Side Rendering

Pre-Rendering

预先渲染,服务端将页面加载好,然后将html发给客户端

Client-Side Rendering

客户端渲染,服务端把JS,CSS文件发过去,客户端(一般是浏览器)负责通过JS构建出完整的Html;

项目结构

image-20230811185019766
  • package.json 包含包和脚本的列表:

    {
        "scripts": {
          "start": "snowpack dev",
          "build": "snowpack build"
        },
        "dependencies": {
          "react": "^17.0.2",
          "react-dom": "^17.0.2"
        },
        "devDependencies": {
          "snowpack": "^3.8.8"
        }
      }
      
    
    • 包:

      • "dependencies": {
        
           "react": "^17.0.2",
        
           "react-dom": "^17.0.2"
        
          },
        
      • React 包表示 React
      • ReactDOM 包用于将应用程序载入浏览器
    • 脚本:

      • "scripts": {
              "start": "snowpack dev",
              "build": "snowpack build"
            },
        
      • start 用于从 Snowpack 运行开发服务器:
        • 它几乎会生成所有 JavaScript 和 HTML 文件。
        • 当文件更改时,它将承载并自动重启服务器。
      • build 用于生成部署所需的生产文件
  • snowpack.config.js 包含 Snowpack 的核心配置。

    • module.exports = {
          mount: {
              'public': '/',
              'src': '/dist'
          }
      }
      
    • mount 将为 Snowpack 服务器创建两个虚拟目录。
      • public 包含所有静态文件(HTML、CSS 和图像等)。 它托管为 /
      • src 包含所有 JSX 文件和关联的 React 文件。 它托管为 dist
  • public 包含所有静态文件。

  • src 包含所有 React 文件。

了解项目结构

核心设置包含两个用于存储代码的主文件夹:

  • public
    • 包含任何 HTML、CSS、图像或其他静态文件
    • 存储 index.html 和 index.css 文件
  • src
    • 包含需要呈现的任何文件
    • 存储所有 .jsx 文件

我们还将创建两个文件,用于配置应用程序:

  • package.json:包含用于应用程序的包和脚本的列表
  • snowpack.config.js:包含 Snowpack 的配置选项

我们的应用程序需要三个主程序包:

  • Snowpack:用于将 JSX 呈现为 HTML 和 JavaScript
  • React:用于创建组件
  • React-DOM:用于载入应用程序

引入

import './index.css'             //引入CSS样式,不需要名字,自动使用
import React from 'react';   //引入组件需要给一个名字,以便使用
import RecipeTitle from './RecipeTitle'    

语法示例

const updatedRecipe = { ...recipe };

作用:把recipe复制一份给updatedRecipe

相当于c#:recipe updatedRecipe=new recipe();

const [recipe, setRecipe] = useState(initialRecipe);

作用:设置一个状态变量 recipe,并将initialRecipe的值赋给它;同时声明了一个函数 setRecipe,用于刷新recipe的值

function ingredientClick(index) {
        const updatedRecipe = { ...recipe };
        updatedRecipe.ingredients[index].prepared = !updatedRecipe.ingredients[index].prepared;
        setRecipe(updatedRecipe);
    }

可以看到这个函数的作用:点击时创建一个recipe的副本,然后将它的对应原料的prepared属性设置为相反,这时候使用setRecipe函数,并传入新的updatedRecipe,更新了Recipe的值;