目录
脚手架创建项目
出版本(生成优化版本)
调试运行
删除依赖和配置(Removes this tool and copies build dependencies, configuration files and scripts into the app directory. If you do this, you can’t go back!)
相关基础知识
React类式组件和函数式组件的区别有哪些呢?
export default也可以写到class
vscode中添加语言支持
设置启动端口号
onClick后直接添加this.addNum会在加载时默认执行一次,这样配置才不会
useEffect,挂载、更新、摧毁
函数式组件
函数组件与 class 组件
函数中root.render修改渲染元素,定时刷新
对象中root.render修改渲染元素
向 class 组件中添加局部的 state
支持的事件
npx create-react-app my-app
cd my-app
npm start
npm run build
npm test
npm run eject
主要要以下几个区别:
(1)语法不同、设计思想不同
(2)生命周期、状态变量
(3)复用性:
(4)优缺点
一、语法不同、设计思想不同
函数式组件是函数式编程思想,而类组件是面向对象编程思想。面向对象编程将属性和方法封装起来,屏蔽很多细节,不利于测试。
二、生命周期、状态变量
类式组件:使用state对象定义状态变量,有诸如componmentDidMount、shouldComponentUpdate等生命周期钩子函数;
函数式组件:没有this,使用一系列的内置hooks实现对应的功能,比如使用useState创建状态变量,使用useEffect实现类似于componmentDidMount、shouldComponentUpdate等生命周期钩子函数的功能。
三、复用性
类式组件:使用hoc(高阶组件)、render propss实现组件的逻辑复用、拓展组件的功能。
函数式组件:使用自定义hooks实现组件的逻辑复用。
四、优缺点
函数式组件:
优点:
缺点:
类式组件:
优点:
缺点:
以上几个问题示例代码如下
import React from 'react'
const msg = "hello"
export default class App extends React.Component {
render() {
return (
{msg}
)
})
}
勾选上trigger后输入后自动添加符号(如输入h1后按tab自动添加)
在node_modules/react-scripts/scripts/start.js中搜索PORT,把原来的3000改成这里我想要的80端口,再npm start就是我想要的端口了
useEffect需要传递两个参数,第一个参数是逻辑处理函数,第二个参数是一个数组
用法
1 2 3 |
useEffect(() => { /** 执行逻辑 */ },[]) |
重要理解
一、第二个参数存放变量,当数组存放变量发生改变时,第一个参数,逻辑处理函数将会被执行
二、第二个参数可以不传,不会报错,但浏览器会无线循环执行逻辑处理函数。
1 2 3 |
useEffect(() => { /** 执行逻辑 */ }) |
三、第二个参数如果只传一个空数组,逻辑处理函数里面的逻辑只会在组件挂载时执行一次 ,不就是相当于 componentDidMount
1 2 3 |
useEffect(() => { /** 执行逻辑 */ },[]) |
四、第二个参数如果不为空数组,如下
1 2 3 4 5 |
const [a, setA] = useState(1); const [b, setB] = useState(2); useEffect(() => { /** 执行逻辑 */ },[a,b]) |
逻辑处理函数会在组件挂载时执行一次和(a或者b变量在栈中的值发生改变时执行一次) 这是不是相当于componentDidMount 和 componentDidUpdate 的结合
五、useEffect第一个参数可以返回一个回调函数,这个回调函数将会在组件被摧毁之前和再一次触发更新时,将之前的副作用清除掉。这就相当于componentWillUnmount。useEffect去除副作用。我们可能会在组件即将被挂载的时候创建一些不断循环的订阅(计时器,或者递归循环)。在组件被摧毁之前,或者依赖数组的元素更新后,应该将这些订阅也给摧毁掉。
没有生命周期,mounted、updated、beforeDestroy,数据更新可以如下实现
import {useState, useEffect} from 'react'
function App(){
useEffect(()=>{
console.log('xx')
}, [num1, num2]) // 这里会监听数据更新后触发执行,如果都想监听则不用添加,[],如果都不想监听那别写了或者[]中为空
return (xxx)
}
export default App;
没有this、没有state状态
Hooks(钩子函数) - React官方提供的hook;开发人员自定义hook
import {useState} from 'react'
function App1(){
// Hook只能用在组件函数中的最顶层,msg为下面使用的变量,setMsg为设置msg的函数
const [msg, setMsg] = useState('你好')
return (
<>
{msg}
// 获取时间显示
It is {new Date().toLocaleTimeString()}.
>
)
}
export default App1;
// 函数组件
function Welcome(props) {
return Hello, {props.name}
;
}
// class组件
class Welcome extends React.Component {
render() {
return Hello, {this.props.name}
;
}
}
// 渲染组件,直接传参props在函数中不能更改(否则会报错),修改需要使用state,state 是私有的,并且完全受控于当前组件
function Welcome(props) { return Hello, {props.name}
;
}
const root = ReactDOM.createRoot(document.getElementById('root'));
const element = ;
root.render(element);
// 组合组件,这里会显示2行Hello xx
function Welcome(props) {
return Hello, {props.name}
;
}
function App() {
return (
);
}
函数中root.render修改渲染元素,定时刷新
import ReactDOM from 'react-dom';
const root = ReactDOM.createRoot(document.getElementById('root'));
function tick() {
const element = (
Hello, world!
It is {new Date().toLocaleTimeString()}.
);
root.render(element);
}
// 定时刷新
setInterval(tick, 1000);
export default tick;
对象中root.render修改渲染元素
-
- 写到render函数中,不需要写入参默认入参在this.props内
- 同上用root.render修改渲染
import React from 'react';
import ReactDOM from 'react-dom';
const root = ReactDOM.createRoot(document.getElementById('root'));
class Clock extends React.Component {
render() {
return (
Hello, world!
It is {this.props.date.toLocaleTimeString()}.
);
}
}
function tick() {
root.render( );
}
setInterval(tick, 1000);
export default tick;
向 class 组件中添加局部的 state
constructor构造函数中设置,super对对象进行初始化
import React from 'react';
import ReactDOM from 'react-dom';
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {date: new Date()};
}
render() {
return (
Hello, world!
It is {this.state.date.toLocaleTimeString()}.
);
}
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render( );
export default Clock;
不要直接修改state,而是应该使用 setState()
this.state = {date: new Date()}; // 构造函数中声明
this.setState({date: 'Hello'}); // 函数处理中设置
React 可能会把多个 setState() 调用合并成一个调用。this.props 和 this.state 可能会异步更新,所以你不要依赖他们的值来更新下一个状态。解决这个问题,可以让
setState() 接收一个函数而不是一个对象。
// Correct
this.setState((state, props) => ({
counter: state.counter + props.increment
}));
组件可以选择把它的 state 作为 props 向下传递到它的子组件中
支持的事件
鼠标事件:onClick 、onContextMenu 、onDoubleClick 、onDrag 、onDragEnd 、onDragEnter 、onDragExit 、onDragLeave 、onDragOver、onDragStart 、onDrop 、onMouseDown 、onMouseEnter 、onMouseLeave 、onMouseMove 、onMouseOut 、onMouseOver 、onMouseUp
键盘事件:onKeyDown 、onKeyPress 、onKeyUp
剪贴板事件:onCopy 、onCut, onPaste
表单事件:onChange 、onlnput、onSubmit
焦点事件:onFocus 、onBlur
触摸事件:onTouchCancel 、onTouchEnd 、onTouchMove 、onTouchStart
UI 事件:onScroll
滚轮事件:onWheel
选择事件:onSelect
图片事件:onLoad 、onError
动画事件:onAnimationStart 、onAnimationEnd 、onAnimationlteration
过技事件:onTransitionEnd