跳转到内容

React

刀刀

9/6/2023

0 字

0 分钟

新版项目创建

下面来创建一个 REACT 项目

  1. 首先登录官网 (opens new window)下载安装NODEJS (opens new window)最新版本

  2. Yarn (opens new window)会缓存它下载的每个包所以无需重复下载

    txt
    npm install -g yarn@berry
  3. 使用 Create React App (opens new window)安装 REACT 项目非常方便,下面来创建项目 daodao

    txt
    npm i -g create-react-app
  4. 创建项目

    npx create-react-app 项目名称
  5. 进入目录并启动项目

    txt
    cd 项目名称
    yarn start

public 文件介绍

  • favicon.ico :网站图标
  • index.html :单文件项目的主文件,其中:
    • <link rel="icon" :网站的图标
    • <meta name="viewport" :移动端适配的头
    • <meta name="theme-color" :安卓手机运行时浏览器搜索栏的颜色
    • <meta name="description" :网站的描述
    • <link rel="apple-touch-icon" :苹果手机创建桌面快捷方式时的图标
    • <link rel="manifest" :应用加壳技术,加壳之后前端 H5 页面改后缀为 .apk 可下载到手机上使用(适用于简单的项目)
  • manifest.josn :应用加壳的配置

src 文件介绍

  • App.css -------- App 组件的样式
  • App.js --------- App 组件
  • App.test.js ---- 用于给 App 做测试
  • index.css ------ 样式
  • index.js ------- 入口文件
  • logo.svg ------- logo 图
  • reportWebVitals.js --- 页面性能分析文件(需要 web-vitals 库的支持)
  • setupTests.js ---- 组件单元测试的文件(需要 jest-dom 库的支持)

开发工具

“vscode logo”的图片搜索结果

建议使用 VSCODE (opens new window)做为开发工具,需要安装的插件如下(点开链接后,点击 Install 按钮安装)

  1. Reactjs code snippets
  2. React Extension Pack
  3. ES7 React/Redux/GraphQL/React-Native snippets react 代码片段插件

声明组件

基本声明

下面在 index.js 入口文件中创建组件最简单的组件。下面的组件像 HTML 但只是像而已。它被称为 JSX 是一个 JavaScript 的语法扩展,它具有 JavaScript 的全部功能。

  • 渲染后的内容将放在 public/index.html 中 ID 为 root 的标签中
js
import React from "react";
import ReactDom from "react-dom";

ReactDom.render(<div>daodao</div>, document.querySelector("#root"));

在 JSX 中可以使用 JS 的功能,要求使用花扩号包裹

js
const name = "刀刀";
ReactDom.render(<div>{name}</div>, document.querySelector("#root"));

函数声明

使用函数返回组件,渲染组件时可以传递参数供组件使用

js
const App = (props) => {
  return <div>{props.name}</div>;
};

ReactDom.render(App({ name: "刀刀" }), document.querySelector("#root"));

调用组件也可以直接使用标签形式,参数以属性形式传递

  • 要求首字母大写
js
import React from "react";
import ReactDom from "react-dom";
const App = (props) => {
  return <div>{props.name}</div>;
};

ReactDom.render(<App name="daodao.com" />, document.querySelector("#root"));

类的声明

我们知道 JS 中的类也是函数,REACT 也可以使用类的方式声明组件,但要保证返回 JSX 组件标签

js
import React, { Component } from "react";
import ReactDom from "react-dom";
class App {
  constructor(props) {
    this.props = props;
  }
  render() {
    return <div>{this.props.name}</div>;
  }
}

ReactDom.render(
  new App({ name: "刀刀" }).render(),
  document.querySelector("#root")
);

如果继承了 Component 基类,会自动绑定参数到 props

js
import React, { Component } from "react";
import ReactDom from "react-dom";
class App extends Component {
  render() {
    return <div>{this.props.name}</div>;
  }
}

ReactDom.render(
  new App({ name: "刀刀" }).render(),
  document.querySelector("#root")
);

更好的是,当继承了 Component 基类

  • 可以使用标签形式调用组件
  • 系统会自动将标签参数绑定到属性 props
  • 注意要求首字母大写
js
import React, { Component } from "react";
import ReactDom from "react-dom";
class App extends Component {
  constructor(props) {
    super(props);
    this.props = props;
  }
  render() {
    return <div>{this.props.name}</div>;
  }
}

ReactDom.render(<App name="刀刀" />, document.querySelector("#root"));

基类会帮助我们绑定数据到 props,所以不写构造函数也可以正常执行

js
import React, { Component } from "react";
import ReactDom from "react-dom";
class App extends Component {
  render() {
    return <div>{this.props.name}</div>;
  }
}

ReactDom.render(<App name="刀刀" />, document.querySelector("#root"));

组件嵌套

下面 App 组件内部引入了 Hd 组件

js
import React, { Component } from "react";
import { render } from "react-dom";

class Hd extends Component {
  render() {
    return <div>Hd组件: {this.props.name} </div>;
  }
}

class App extends Component {
  render() {
    return (
      <div>
        <Hd name="daodao.com" />
        App: {this.props.name}
      </div>
    );
  }
}
render(<App name="刀刀" />, document.getElementById("root"));

根组件

根据件就像 HTML 标签中的 html 一样,所有其它标签都在它的里面。根组件也是这个特点,在里面构建不同组件产生不同界面。

组件一般都是独立的文件,下面创建 App.js 文件构建根组件

js
import React, { Component } from "react";
export default class App extends Component {
  render() {
    return <div>刀刀</div>;
  }
}

在入口文件中导入组件并渲染

js
import React, { Component } from "react";
import { render } from "react-dom";
import App from "./App";
render(<App />, document.querySelector("#root"));

注释规范

组件中的注释使用 JS 注释规范,因为是 JS 所以要使用花扩号包裹。

js
class App extends Component {
  render() {
    return (
      <div>
        {/* 刀刀 */}
        {this.props.name}
      </div>
    );
  }
}

样式处理

下面介绍多种样式的处理方式

行级样式

REACT 中定义样式也非常简单,下面是定义 STYLE 行样式

js
class App extends Component {
  render() {
    return <div style={{ color: "red" }}>App: {this.props.name}</div>;
  }
}
render(<App name="刀刀" />, document.getElementById("root"));

以对象形式声明样式

js
class App extends Component {
  render() {
    const style = {
      backgroundColor: "red",
      color: "blue",
    };
    return <div style={style}>刀刀</div>;
  }
}
render(<App name="刀刀" />, document.getElementById("root"));

类的声明

下面来体验类样式的定义

  1. 组件同级目录定义 App.css,内容如下
    css
    .bg-color {
      background: red;
    }
  2. 在 index.js 中使用 className 属性来声明类
    js
    import React, { Component } from "react";
    import { render } from "react-dom";
    import "./App.css";
    class App extends Component {
      render() {
        return <div className="bg-color">App: {this.props.name}</div>;
      }
    }
    render(<App name="刀刀" />, document.getElementById("root"));

当然也可以使用 JS 程序计算,下面是使用三元表达式的计算

js
class App extends Component {
  render() {
    return (
      <div className={true ? "bg-color" : "hd"}>App: {this.props.name}</div>
    );
  }
}

第三方库

classnames

classnames (opens new window)是一个动态设置样式类的库,比如不同用户组使用不同样式。

首先来安装库

txt
npm i classnames

在 index.js 声明的组件中使用

js
import className from "classnames";
import "./App.css";
class App extends Component {
  render() {
    return (
      <div className={className("bg-color", { hd: true })}>
        App: {this.props.name}
      </div>
    );
  }
}
render(<App name="刀刀" />, document.getElementById("root"));

styled-components

使用社区提供的第三方库来控制样式,下面是使用 styled-components (opens new window)组件来控制样式

安装扩展包

txt
npm i styled-components

下面在组件中使用

js
...

//声明样式组件Wrapper 最终渲染成section
const Wrapper = styled.section`
  padding: 4em;
  background: papayawhip;
`;

class App extends Component {
  render() {
    return (
      <Wrapper>
        <div>App: {this.props.name}</div>
      </Wrapper>
    );
  }
}
render(<App name="刀刀" />, document.getElementById("root"))

样式模块化

  1. 通过下载 lessscss 等预处理器来设置单独的样式模块
    scss
    .hello {
      .title {
        color: red;
      }
    }
  2. 通过 module 关键词做模块化操作
    • 样式文件中间添加 .model 关键字
      css
      index.module.css
    • 引入的时候使用关键字接收
      javascript
      import hello from "./index.module.css";
    • 使用的时候通过 关键字.类名 的方式使用
      jsx
      <div className={hello.title}></div>

实例操作

axiox 请求

跨域处理

  1. 配置 proxy 代理

    package.json 文件中配置代理,通过服务器没有同源策略的特性避免跨域的问题,其参数是自己需要请求的服务器 IP 与端口

    json
    {
      // ...
      "proxy": "http://localhost:5000/"
    }

    说明:

    1. 优点:配置简单,前端请求资源时可以不加任何前缀。
    2. 缺点:不能配置多个代理。
    3. 工作方式:上述方式配置代理,当请求了 3000 不存在的资源时,那么该请求会转发给 5000 (优先匹配前端资源)
  2. 配置代理文件

    1. 第一步:创建代理配置文件

      在 src 下创建配置文件:src/setupProxy.js

    2. 编写 setupProxy.js 配置具体代理规则:

      javascript
      const proxy = require("http-proxy-middleware"); // react18之前
      const { createProxyMiddleware } = require("http-proxy-middleware"); // react18之后
      
      module.exports = function (app) {
        app.use(
          proxy("/api1", {
            //api1是需要转发的请求(所有带有/api1前缀的请求都会转发给5000)
            target: "http://localhost:5000", //配置转发目标地址(能返回数据的服务器地址)
            changeOrigin: true, //控制服务器接收到的请求头中host字段的值
            /*
                changeOrigin设置为true时,服务器收到的请求头中的host为:localhost:5000
                changeOrigin设置为false时,服务器收到的请求头中的host为:localhost:3000
                changeOrigin默认值为false,但我们一般将changeOrigin值设为true
            */
            pathRewrite: { "^/api1": "" }, //去除请求前缀,保证交给后台服务器的是正常请求地址(必须配置)
          }),
          proxy("/api2", {
            target: "http://localhost:5001",
            changeOrigin: true,
            pathRewrite: { "^/api2": "" },
          })
        );
      };

    说明:

    1. 优点:可以配置多个代理,可以灵活的控制请求是否走代理。
    2. 缺点:配置繁琐,前端请求资源时必须加前缀。