文章目录
React 入门
前言
最近接手一个
React
项目,还是大屏展示的,似乎还挺简单的,但是也不太会 React,所以有了这篇文章,我还在努力学vue
呢,哎突然插进来这个,哈哈哈。
介绍
官方介绍,似乎来源于 facebook
新建并启动项目
在命令行里输入如下命令
npx create-react-app hello-react
什么是 npx 呢? 可以看一下阮一峰的教程
主要点:
- Node 自带 npm 模块,所以可以直接使用 npx 命令。万一不能用,就要手动安装一下
- npx 想要解决的主要问题,就是调用项目内部安装的模块
- 避免安装全局模块
安装过程如下(我网络比较慢…)
安装好后,cd
到你的项目下,然后执行 npm run start
即可启动项目。
create-react-app 项目结构
创建好后的项目如下
有些比较常见,下面是 react
项目比较重要的文件说明
├── README.md 文档
├── public 静态资源
│ ├── favicon.ico
│ ├── index.html
│ └── manifest.json
└── src 源码
├── App.css
├── App.js 根组件
├── App.test.js
├── index.css 全局样式
├── index.js 入口文件
├── logo.svg
└── serviceWorker.js pwa 支持
├── package.json npm 包依赖
执行如下命令配置暴露项:
npm run eject
执行后,项目目录会新增加 config
以及 script
文件夹
React 和 ReactDOM
可以在 scr/index.js
目录下查看相关代码
React
负责逻辑控制,数据 -> VDOMReactDom
渲染实际DOM
,VDOM -> DOMReact
使⽤用JSX
来描述UI
babel-loader
把JSX
编译成相应的JS
对象React.createElement
再把这个JS对象
构造成React
需要的虚拟dom
。babel-loader
把JSX
编译成相应的JS
对象,React.createElement
再把这个JS
对象构造成React
需
要的虚拟dom
。
JSX 语法
JSX
是⼀种 JavaScript
的语法扩展,其格式比较像模版语言,但事实上完全是在JavaScript
内部实现的。
基本使⽤
表达式{}
的使⽤
函数
函数也是合法表达式
const obj = {
fistName: "王",
lastName: "先生",
};
function formatName(name) {
return name.fistName + " " + name.lastName;
}
const jsx = <div>{formatName(obj)}</div>;
ReactDOM.render(jsx, document.getElementById("root"));
如果直接要展示对象的话,会报错
jsx 对象
const jsxObject = <div>我是 jsx 对象</div>;
const jsx = (
<div>
<div>{jsxObject}</div>
</div>
);
ReactDOM.render(jsx, document.getElementById("root"));
条件表达
三目运算符!
或者是 &&
数组
想要循环数组的话可以这么干
注意:
-
li
需要添加key
属性,不然会报错 -
如果是
forEach
的话就不行了,因为map
是返回新的数组,forEach
啥都不返回
添加属性
也是通过表达式
src 属性
这里给 img
标签添加 src
属性
元素类名
在添加一个 class
属性,通过 className
来添加
行内 Style
首先是 style 属性,用表达式包上一层{}
然后里面写个对象,所以又有一层{}
CSS 模块化
css 的模块化如下图所示,类名自动帮你改了,防止重复,对于大型项目来说是有用的
也可以安装一下 sass
,用于写 .scss
文件
npm install sass -D
VScode 插件
这里推荐一个 vscode
的插件,用于快速构建基础代码 Reactjs code snippets
比方说构一个 Class
组件 rcc
,Function
组件rfc
然后,写状态:con
,之后sst
设置状态
组件
组件,从概念上类似于 JavaScript
函数。有两种形式:class
组件和function
组件。
Class 组件
基础结构
首先新建一个 page
文件夹,然后新建 js
文件,里面的内容如下
import React, { Component } from 'react'
export default class ClassComponent extends Component {
render() {
return (
<div>
<h3>i am ClassComponent</h3>
</div>
)
}
}
然后再主入口文件中引入一下
Class 实例:时钟(组件属性、声明周期)
在构造函数constructor
中设置组件的属性
这里使用到了componentDidMount
这个声明周期
整体的思路如下:
代码
import React, { Component } from 'react'
export default class ClassComponents extends Component {
constructor(props) {
super(props)
// 使⽤用state属性维护状态,在构造函数中初始化状态
this.state = {
date: new Date(),
}
}
// react 的生命周期
// 组件加载完后会执行
componentDidMount() {
// 使⽤用setState⽅方法更更新状态
this.timer = setInterval(() => {
this.setState({
date: new Date(),
})
}, 1000)
}
// 组件卸载之前执行
componentWillUnmount() {
console.log('componentWillUnmount')
clearInterval(this.timer)
}
componentDidUpdate() {
console.log('componentDidUpdate')
}
render() {
const { date } = this.state
return (
<div>
<span>{date.toLocaleTimeString()}</span>
</div>
)
}
}
Function 组件
函数组件通常⽆无状态,仅关注内容展示,返回渲染结果即可
从React16.8开始引⼊入了了hooks,函数组件也能够拥有状态。
用 function
组件创建⼀个Clock
代码执行后如下图所示:
关于 setState
正确使用 setState
setState(partialState, callback)
partialState:object|function
用于产生与当前state合并的⼦集。callback:function state
更新之后被调⽤
关于 setState() 你应该了解三件事
不要直接修改 State
首先,直接修改的话会提示你
而且直接修改的话也不会更新组件
// 错误示范
this.state.date = new Date();
// 正确示范
this.setState({
date: new Date(),
})
State 的更新可能是异步的
出于性能考虑,React
可能会把多个 setState()
调⽤合并成一个调⽤。 观察以下例子中log
的值和button
显示的counter
。
如果要获取到最新状态值有以下方式:
-
在回调中获取状态值
-
使⽤定时器
-
原生事件中修改状态
State 的更新会被合并
先看一下被合并的情况
那要怎么解决呢,还记得 setState()
的第一个参数可以传递函数吗!
或者这样
changeValue = v => {
this.setState(state => ({ counter: state.counter + v }));
};
setCounter = () => {
this.changeValue(1);
this.changeValue(2);
};
生命周期
16.4 版本之前的生命周期
找了一张图啊,先放这儿。
然后我就实验一下呗!
mounted
好实验,update
需要更新一下数据才能触发生命周期钩子,所以这里我在componentWillMount
中写了个延时定时器
componentWillUnmount
组件将要卸载时触发,可以用于取消定时器之类的操作componentWillReceiveProps
:组件初次渲染时不会触发,只有已挂载的组件接收新的props
的时候才会执行。
16.4 版本之后的生命周期
被废弃的生命周期
V17
可能会废弃的三个⽣生命周期函数⽤用getDerivedStateFromProps
替代,
componentWillMount
componentWillReceiveProps
componentWillUpdate
⽬前使用的话加上 UNSAFE_
,否则会报 Warning
如果不想⼿动给将要废弃的生命周期添加 UNSAFE_
前缀,可以⽤下⾯的命令。
npx react-codemod rename-unsafe-lifecycles <path>
初次使用这个命令会安装一个依赖 react-codemod
:
安装完依赖之后再次执行该命令即可。
新引入的生命周期
新引⼊的两个生命周期函数
getDerivedStateFromProps
:会在调⽤render
⽅法之前调用,并且在初始挂载及后续更新时都会被
调用,它应返回一个对象来更新state
,如果返回null
则不更新任何内容。(这个跟原先unsafe
的生命周期是冲突的,不能共用!)getSnapshotBeforeUpdate
:在render
之后,在componentDidUpdate
之前。