Web--React框架

配置环境

导航:React

React官网

安装Git Bash(仅限使用Windows的同学,使用Mac和Linux的同学无需安装)

安装地址

安装Nodejs

安装地址

安装create-react-app

打开Git Bash,执行:

npm i -g create-react-app

安装VSCode的插件

  • Simple React Snippets
  • Prettier - Code formatter

创建React App

在目标目录下打开Git Bash,在终端中执行:

create-react-app react-app  # 可以替换为其他app名称
 
cd react-app
npm start  # 启动应用

JSX

React中的一种语言,会被Babel编译成标准JavaScript。

ES6

使用bind()函数绑定this取值

在JavaScript中,函数里的this指向的是执行时的调用者,而非定义时所在的对象。

例如:

const person = {
  name: "yxc",
  talk: function() {
    console.log(this);
  }
}
 
person.talk();
 
const talk = person.talk;
talk();

运行结果:

{name: 'yxc', talk: ƒ}
Window

bind()函数,可以绑定this的取值。例如:

const talk = person.talk.bind(person);

箭头函数的简写方式

const f = (x) => {
  return x * x;
};

可以简写为:

const f = x => x * x;

箭头函数不重新绑定this的取值

例如:

const person = {
  talk: function() {
    setTimeout(function() {
      console.log(this);
    }, 1000);
  }
};
 
person.talk();  // 输出Window
const person = {
  talk: function() {
    setTimeout(() => {
      console.log(this);
    }, 1000);
  }
};
 
person.talk();  // 输出 {talk: f}

对象的解构

例如:

const person = {
  name: "yxc",
  age: 18,
  height: 180,
};
 
const {name : nm, age} = person;  // nm是name的别名

数组和对象的展开

例如:

let a = [1, 2, 3];
let b = [...a];  // b是a的复制
let c = [...a, 4, 5, 6];
const a = {name: "yxc"};
const b = {age: 18};
const c = {...a, ...b, height: 180};

Named 与 Default exports

  • Named Export:可以export多个,import的时候需要加大括号,名称需要匹配
  • Default Export:最多export一个,import的时候不需要加大括号,可以直接定义别名

Components

创建项目

创建项目box-app

create-react-app box-app
cd box-app
npm start

安装bootstrap库:

npm i bootstrap

bootstrap的引入方式:

import 'bootstrap/dist/css/bootstrap.css';

创建Component

创建按钮

当子节点数量大于1时,可以用<div><React.Fragment>将其括起来。

内嵌表达式

JSX中使用{}嵌入表达式。

设置属性

  • class -> className
  • CSS属性:background-color -> backgroundColor,其它属性类似

数据驱动改变Style

渲染列表

  • 使用map函数
  • 每个元素需要具有唯一的key属性,用来帮助React快速找到被修改的DOM元素。

Conditional Rendering

利用逻辑表达式的短路原则。

  • 与表达式中 expr1 && expr2,当expr1为假时返回expr1的值,否则返回expr2的值
  • 或表达式中 expr1 || expr2,当expr1为真时返回expr1的值,否则返回expr2的值

绑定事件

  • 注意妥善处理好绑定事件函数的this

修改state

  • 需要使用this.setState()函数
  • 每次调用this.setState()函数后,会重新调用this.render()函数,用来修改虚拟DOM树。React只会修改不同步的实际DOM树节点。

给事件函数添加参数

例子
index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import 'bootstrap/dist/css/bootstrap.css';
import Box from './components/box';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <div className="container"><Box/></div>
  </React.StrictMode>
)

box.jsx

import React, { Component } from 'react';

class Box extends Component {
    state = { 
        solutions: [
            {key: 10, number: 1152, title: "加工零件0", view: 20},
            {key: 11, number: 1153, title: "加工零件1", view: 21},
            {key: 12, number: 1154, title: "加工零件2", view: 22},
            {key: 13, number: 1155, title: "加工零件3", view: 23},
            {key: 14, number: 1156, title: "加工零件4", view: 24},
            {key: 15, number: 1157, title: "加工零件5", view: 25},
            {key: 16, number: 1158, title: "加工零件6", view: 26},
            {key: 17, number: 1159, title: "加工零件7", view: 27},
            {key: 18, number: 1160, title: "加工零件8", view: 28},
        ]
     } 

    hundleClickDelete = (s) => {
        if (this.state.solutions.length === 0) return <p>没有题解了</p>

        let solutions = this.state.solutions.filter(solution => solution != s);
        this.setState({
            solutions: solutions
        });
    }
    render() { 
        return (
                <table className="table">
                    <thead>
                        <tr>
                            <th>#</th>
                            <th>标题</th>
                            <th>阅读</th>
                            <th>操作</th>
                        </tr>
                    </thead>
                    <tbody>
                        {this.state.solutions.map(solution => (
                            <tr key = {solution.key}>
                                <td>{solution.number}</td>
                                <td>{solution.title}</td>
                                <td>{solution.view}</td>
                                <td><button className='btn btn-danger' onClick={() => this.hundleClickDelete(solution)}>删除</button></td>
                            </tr>
                        ))}
                    </tbody>
                </table>
        );
    }
}
 
export default Box;

组合

创建Boxes组件

Boxes组件中包含一系列Box组件。

从上往下传递数据

通过this.props属性可以从上到下传递数据。

传递子节点

通过this.props.children属性传递子节点

从下往上调用函数

注意:每个组件的this.state只能在组件内部修改,不能在其他组件内修改。

每个维护的数据仅能保存在一个this.state

  • 不要直接修改this.state的值,因为setState函数可能会将修改覆盖掉。

创建App组件

包含:

  • 导航栏组件
  • Boxes组件

注意:

  • 要将多个组件共用的数据存放到最近公共祖先的this.state中。

无状态函数组件

  • 当组件中没有用到this.state时,可以简写为无状态的函数组件。
  • 函数的传入参数为props对象

组件的生命周期

  • Mount周期,执行顺序:constructor() -> render() -> componentDidMount()
  • Update周期,执行顺序:render() -> componentDidUpdate()
  • Unmount周期,执行顺序:componentWillUnmount()

路由

Web分类

  • 静态页面:页面里的数据是写死的
  • 动态页面:页面里的数据是动态填充的
    • 后端渲染:数据在后端填充
    • 前端渲染:数据在前端填充

安装环境

  • VSCODE安装插件:Auto Import - ES6, TS, JSX, TSX
  • 安装Route组件:npm i react-router-dom

Route组件介绍

  • BrowserRouter:所有需要路由的组件,都要包裹在BrowserRouter组件内
  • Link:跳转到某个链接,to属性表示跳转到的链接
  • Routes:类似于C++中的switch,匹配第一个路径
  • Route:路由,path属性表示路径,element属性表示路由到的内容

URL中传递参数

解析URL:

<Route path="/linux/:chapter_id/:section_id/" element={<Linux />} />

获取参数,类组件写法:

import React, { Component } from 'react';
import { useParams } from 'react-router-dom';
 
class Linux extends Component {
    state = {  } 
    render() {
        console.log(this.props.params);
        return <h1>Linux</h1>;
    }
}
 
export default (props) => (
    <Linux
        {...props}
        params={useParams()}
    />
)

函数组件写法:

import React, { Component } from 'react';
import { useParams } from 'react-router-dom';
 
const Linux = () => {
    console.log(useParams());
    return (<h1>Linux</h1>);
}
 
export default Linux;

Search Params传递参数

类组件写法:

import React, { Component } from 'react';
import { useSearchParams } from 'react-router-dom';
 
class Django extends Component {
    state = {
        searchParams: this.props.params[0],  // 获取某个参数
        setSearchParams: this.props.params[1],  // 设置链接中的参数,然后重新渲染当前页面
    }
     
    handleClick = () => {
        this.state.setSearchParams({
            name: "abc",
            age: 20,
        })
    }
 
    render() {
        console.log(this.state.searchParams.get('age'));
        return <h1 onClick={this.handleClick}>Django</h1>;
    }
}
 
export default (props) => (
    <Django
        {...props}
        params={useSearchParams()}
    />
);

函数组件写法:

import React, { Component } from 'react';
import { useSearchParams } from 'react-router-dom';
 
const Django = () => {
    let [searchParams, setSearchParams] = useSearchParams();
    console.log(searchParams.get('age'));
    return (<h1>Django</h1>);
}
 
export default Django;

重定向

使用Navigate组件可以重定向。

<Route path="*" element={ <Navigate replace to="/404" /> } />

嵌套路由

<Route path="/web" element={<Web />}>
    <Route index path="a" element={<h1>a</h1>} />
    <Route index path="b" element={<h1>b</h1>} />
    <Route index path="c" element={<h1>c</h1>} />
</Route>

注意:需要在父组件中添加<Outlet />组件,用来填充子组件的内容。

Redux

redux将所有数据存储到树中,且树是唯一的。

Redux基本概念

  • store:存储树结构。
  • state:维护的数据,一般维护成树的结构。
  • reducer:对state进行更新的函数,每个state绑定一个reducer。传入两个参数:当前stateaction,返回新state
  • action:一个普通对象,存储reducer的传入参数,一般描述对state的更新类型。
  • dispatch:传入一个参数action,对整棵state树操作一遍。

React-Redux基本概念

  • Provider组件:用来包裹整个项目,其store属性用来存储reduxstore对象。
  • connect(mapStateToProps, mapDispatchToProps)函数:用来将store与组件关联起来。
    • mapStateToProps:每次store中的状态更新后调用一次,用来更新组件中的值。
    • mapDispatchToProps:组件创建时调用一次,用来将storedispatch函数传入组件。

安装

  • npm i redux react-redux @reduxjs/toolkit

学习自AcWing Web应用课

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ˇasushiro

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值