React-进阶(6)
懒加载
第一种方式
1 | import("./math").then(math => { |
第二种方式
1 | import React, { Suspense } from 'react'; |
Context
Context 提供了一个无需为每层组件手动添加 props,就能在组件树间进行数据传递的方法。
Context 提供了一种在组件之间共享值的方式,而不必显式地通过组件树的逐层传递 props。
使用Context的场景
Context 设计目的是为了共享那些对于一个组件树而言是“全局”的数据,例如当前认证的用户、主题或首选语言。举个例子,在下面的代码中,我们通过一个 “theme” 属性手动调整一个按钮组件的样式:
在没使用Conext之前遇到的问题
1 | class App extends React.Component { |
使用Context就可避免这种情况
1 | // Context 可以让我们无须明确地传遍每一个组件,就能将值深入传递进组件树。 |
要谨慎使用Context,会导致组件复用性变差.
函数式组件
起初的函数式组件的特点:
- 无生命周期
- 没有this
- 没有state状态
Hooks
Hook只能用在函数组件的最顶层
官方Hook:
- useState渲染参数只会在组件首次渲染时使用,再次更新时会被忽略。如果初始值需要计算,则可以使用回调函数的方式进行返回值计算。
1
2const [count, setCount] = useState(0)
// 通过setCount修改count值 - useEffect
副作用,什么是副作用?
对于主作用,就是数据更新,视图重新渲染。其他都是副作用,例如生命周期、ajax、手动修改DOM、localStorage操作等。
能够模仿以下生命周期钩子
- mounted
- updated
- beforeDestory
第一个参数是回调函数,挂载时会触发该函数,第二个参数是数组,会对数组中变量的变化进行监听,从而调用相应回调函数。如果第二个参数传一个空数组,则该副作用不会感知变量的更新。执行时机永远都是组件DOM渲染更新之后1
2
3
4
5
6
7
8
9
10
11
12const [count1, setCount1] = useState(0)
const [count2, setCount2] = useState(0)
useEffect(() => {
console.log('模拟mounted挂载完成');
console.log('count1和count2初始化或更新');
return () => {
console.log('模拟beforeDestory');
}
}, [count1, count2])
useEffect(() => {
console.log('模拟mounted挂载完成');
}, [])
两个参数 - 默认状态,首次执行,每次组件更新执行(无第二个参数)
- 首次执行(添加[])
- 首次执行,特定依赖项变化后执行(添加形如[count, num])
useContext
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20import React, { createContext, useContext } from 'react'
const MyContext = createContext()
function Father() {
return <Son></Son>
}
function Son() {
const val = useContext(MyContext)
return <div>{'通过Context传递过来的值:' + val}</div>
}
export default function Context() {
return (
<MyContext.Provider value={'aaa'}>
<Father></Father>
</MyContext.Provider>
)
}useRef
获取DOM节点
使用步骤:
- 导入useRef函数
- 执行useRef函数传入null,返回值为一个对象,内部有current属性存放拿到的DOM对象
- 通过ref绑定要获取的组件或元素
- useCallback、memo与useMemo
这三者是用来性能优化的