章节回顾:
目录
卸载组件api
ReactDOM.unmountComponentAtNode(container)
从 DOM 中卸载组件,会将其事件处理器(event handlers)和 state 一并清除。
如果指定容器上没有对应已挂载的组件,这个函数什么也不会做。
如果组件被移除将会返回 true,如果没有组件可被移除将会返回 false。
引入ReactDOM方式变了
以前的版本是:
import ReactDOM from 'react-dom';
现在的方式是:
import * as ReactDOM from 'react-dom/client';
root的渲染方式变了
以前版本是:
import ReactDOM from 'react-dom';
ReactDOM.render(
<App />,
document.querySelector('#root')
)
现在的方法是:
import * as ReactDOM from 'react-dom/client';
const wrap = document.querySelector('#root');
const root = ReactDOM.createRoot(wrap)
root.render(<App />)
什么是单页面应用?
单页面应用(single-page application),是一个应用程序,它可以加载单个 HTML 页面,
以及运行应用程序所需的所有必要资源(例如 JavaScript 和 CSS)。
与页面或后续页面的任何交互,都不再需要往返 server 加载资源,即页面不会重新加载。
简单理解,就是一个页面里面的内容切换,通过路由处理。
传递事件函数的多种写法
第一种:
<div onClick={() => {handleClick()}}>
</div>
第二种:
<div onClick={handleClick}>
</div>
两种写法是等价的,第一种可以传递参数,第二种在没参数时,写法比较简便。
React中的节流和防抖
使用lodash来处理。官方文档中有在class组件中使用lodash的示例。
所以本次记录的是在react函数组件中使用lodash
安装
npm i lodash --save
引入
import _ from 'lodash'
节流
// 不带参数的
import React from 'react'
import './index.css'
import _ from 'lodash'
const DemoLoadash = () => {
const handleClick = () => {
console.log('click')
}
const handleClickThrottle = _.throttle(handleClick, 1000)
return <div
className='loadash'
onClick={handleClickThrottle}
></div>
}
export default DemoLoadash
// 带参数的
import React from 'react'
import './index.css'
import _ from 'lodash'
const DemoLoadash = () => {
const handleClick = (data) => {
console.log(data)
}
// 通过_.throttle把handleClick变成一个节流函数handleClickThrottle
// 有效间隔时间是1000ms
const handleClickThrottle = _.throttle(handleClick, 1000)
return <div
className='loadash'
onClick={() => handleClickThrottle('click')}
></div>
}
export default DemoLoadash
防抖
import React from 'react'
import './index.css'
import _ from 'lodash'
const DemoLoadash = () => {
const handleClick = (data) => {
console.log(data)
}
// 通过_.debounce把handleClick变成一个防抖函数handleClickDebounce
// 有效间隔时间是1000ms
const handleClickDebounce = _.debounce(handleClick, 1000)
return <div
className='loadash'
onClick={() => handleClickDebounce('click')}
></div>
}
export default DemoLoadash
state 和 props 之间的区别是什么?
props(“properties” 的缩写)和 state 都是普通的 JavaScript 对象。
它们都是用来保存信息的,这些信息可以控制组件的渲染输出,
而它们的一个重要的不同点就是:props 是传递给组件的(类似于函数的形参),
而 state 是在组件内被组件自己管理的(类似于在一个函数内声明的变量)。
注意:setState很可能是异步的
也可以说,setState在绝大多数情况下,都是异步调用的。
调用之后,并不能直接在它后面获取到最新的state。
举个例子:
import React, { useState } from 'react'
const Demo = () => {
const [num, setNum] = useState(0)
const handleClick = () => {
setNum(num + 1)
console.log('当前的num值是:', num)
}
return <div>
<h3>{num}</h3>
<button onClick={handleClick}>click me</button>
</div>
}
export default Demo
点击按钮,让num增加1,
在handleClick
中,调用了setNum(num + 1)
然后紧接着就打印当前的num,这时候,得到的num值仍然是增加前的旧值。
并非是增加1后的新的num。
再比如:
import React, { useState } from 'react'
const Demo = () => {
const [num, setNum] = useState(0)
const handleClick = () => {
setNum(num+1)
setNum(num+1)
setNum(num+1)
}
return <div>
<h3>{num}</h3>
<button onClick={handleClick}>click me</button>
</div>
}
export default Demo
点击之后,连续调用三次setNum,
如果setNum是同步的,每次点击,都会让num增加3
但是实际上,每个setNum都是在旧值的基础上增加1的,
所以每次点击仍然只会增加1
既然这样,怎么在每次调用后立即获取到最新的state呢?
给setState传递一个函数
setState(state => {...操作state})
函数里的state,就是最新的state值。
示例
import React, { useState } from 'react'
const Demo = () => {
const [num, setNum] = useState(0)
const handleClick = () => {
setNum(num => num+1)
setNum(num => num+1)
setNum(num => num+1)
}
return <div>
<h3>{num}</h3>
<button onClick={handleClick}>click me</button>
</div>
}
export default Demo
此时再点击按钮,可以发现,每次都是增加3
避免深层次嵌套
单个项目,文件结构一定避免嵌套层级过多,不然会给项目增加很多难度。
Virtual DOM 及内核
什么是Virtual DOM?
它是一个DOM树对象。
什么是 “React Fiber”?
Fiber 是 React 16 中新的协调引擎。它的主要目的是使 Virtual DOM 可以进行增量式渲染。
至此,react官方文档基本结束。
扫清了一些关于react 的知识盲点。