Web学习(六) React
1.配置环境
React官网
安装Nodejs:https://nodejs.org/en/
安装create-react-app
打开Git Bash或者powershell,执行:
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 # 启动应用
看到此界面即配置成功。
2.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的时候不需要加大括号,可以直接定义别名
3.Components
3.1创建项目
创建项目box-app:
create-react-app box-app
cd box-app
npm start
安装bootstrap库:
npm i bootstrap
bootstrap的引入方式:
import 'bootstrap/dist/css/bootstrap.css';
3.2创建Component
3.3 创建按钮
当子节点数量大于1时,可以用
3.4 内嵌表达式
JSX中使用{}嵌入表达式。
3.5 设置属性
class -> className
CSS属性:background-color -> backgroundColor,其它属性类似
3.6 数据驱动改变Style
3.7 渲染列表
使用map函数
每个元素需要具有唯一的key属性,用来帮助React快速找到被修改的DOM元素。
3.8 Conditional Rendering
利用逻辑表达式的短路原则。
与表达式中 expr1 && expr2,当expr1为假时返回expr1的值,否则返回expr2的值
或表达式中 expr1 || expr2,当expr1为真时返回expr1的值,否则返回expr2的值
3.9 绑定事件
注意妥善处理好绑定事件函数的this
3.10 修改state
需要使用this.setState()函数
每次调用this.setState()函数后,会重新调用this.render()函数,用来修改虚拟DOM树。React只会修改不同步的实际DOM树节点。
3.11 例子:box_move
可以通过按钮实现对box的水平移动
自动补全:
imrc:
import React, { Component } from 'react';
cc:
class extends Component {
state = { }
render() {
return ();
}
}
export default ;
index.js:
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import 'bootstrap/dist/css/bootstrap.css';
import Box from './componets/box';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<Box />
</React.StrictMode>
);
box.jsx:
import React, { Component } from 'react';
class Box extends Component {
state = {
x: 1,
};
handleClickLeft = (step) => {
// 需要使用setState函数修改x的值,才可以影响到render函数
this.setState(
{x : this.state.x - step}
)
}
handleClickRight = () => {
this.setState(
{x : this.state.x + 1}
)
}
render() {
return (
<React.Fragment>
<div style={
{
width:"50px",
height:"50px",
backgroundColor:"lightblue",
marginLeft:this.state.x //通过此属性来修改位置
}
}>{this.state.x}</div>
<button onClick={() => this.handleClickLeft(10)} className='btn btn-primary m-2'>left</button>
<button onClick={this.handleClickRight} className='btn btn-danger m-2'>right</button>
{/* 通过onClick绑定函数 */}
</React.Fragment>
);
}
}
export default Box;
3.12 例子2:题解列表
index.js:
import React from 'react';
import ReactDOM from 'react-dom/client';
import Solution from './components/solution';
import './index.css';
import 'bootstrap/dist/css/bootstrap.css';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<div className='container'>
<Solution />
</div>
</React.StrictMode>
);
solution.jsx:
import React, { Component} from 'react';
class Solution extends Component {
state = {
solutions: [
{key: 0, number: 1164, title: "加工零件1", views: 2930},
{key: 1, number: 1165, title: "加工零件2", views: 2931},
{key: 2, number: 1166, title: "加工零件3", views: 2932},
{key: 3, number: 1167, title: "加工零件4", views: 2933},
{key: 4, number: 1168, title: "加工零件5", views: 2934},
{key: 5, number: 1169, title: "加工零件6", views: 2935},
{key: 6, number: 1170, title: "加工零件7", views: 2936},
{key: 7, number: 1171, title: "加工零件8", views: 2937},
]
};
//添加元素
handleDelete = (s) => {
const solutions = this.state.solutions.filter(solution => solution !== s);
// filter实现遍历所有元素,留下符合要求的元素,即对不符合要求的元素进行删除
this.setState({
solutions : solutions
});
}
//删除元素
handleAdd = () => {
const solutions = [...this.state.solutions,{
key: this.state.solutions.length+1, number: 1111, title: "xxxxx", views: 1111
}];
this.setState({
solutions:solutions
})
}
render() {
if(this.state.solutions.length === 0)
{
return <p>没有题解了</p>
}
return(
<div>
<div>
<button onClick={() => this.handleAdd()} className='btn btn-success'>add</button>
</div>
<table className='table'>
<thead>
<tr>
<th>#</th>
<th>标题</th>
<th>阅读</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{
this.state.solutions.map(solutions => (
<tr key={solutions.key}>
<td>{solutions.number}</td>
<td>{solutions.title}</td>
<td>{solutions.views}</td>
<td><button onClick={() => this.handleDelete(solutions)} className='btn btn-danger'>删除</button></td>
{/* 这里handleDelete传入的参数为solutions */}
</tr>
)
)
}
</tbody>
</table>
</div>
);
}
}
export default Solution;