npx是什么?
安装
npx create-react-app my-app --template typescript
hook官方地址
useEffect有两个参数,useEffect(function, array?) : 第一个参数是一个方法,第二个参数可选,为数组类型。当第二个参数不填时,每次渲染都会执行第一个参数的方法;当第二个参数设置为[]空数组时,只有当组件第一次挂载时,才会执行第一个参数的方法;当第二个参数数组有值,例如[a,b],只有当a和b发生变化时,才会执行第一个参数的方法。
其中第一个参数function可以有返回值,返回值是也是一个function
import React, { useState, useEffect } from 'react'
const MouseTracker: React.FC = () => {
const [positions, setPositions] = useState({ x: 0, y: 0 })
useEffect(() => {
console.log('add effect', positions.x)
const updateMouse = (e: MouseEvent) => {
console.log('inner')
setPositions({ x: e.clientX, y: e.clientY })
}
document.addEventListener('click', updateMouse)
return () => {
console.log('remove effect', positions.x)
document.removeEventListener('click', updateMouse)
}
}, [])//代表在只有什么变化的时候才用effect
console.log('before render', positions.x)
return (
<p>X: {positions.x}, Y : {positions.y}</p>
)
}
export default MouseTracker
用法示例,在class组件中如果需要在组件挂载后和数据更新后做同一件事,我们会这样做:
componentDidMount() {
}
componentDidUpdate() {
}
可以看出来,如果逻辑复杂后,代码看起来不优雅,且容易造成逻辑混乱,而使用useEffect:
useEffect(() => {
});
此刻已经看到了useEffect的基本用法,除此之外,他还可以绑定触发更新的依赖状态,默认是状态中任何数据发生变化副作用都会执行,如:
import { useState, useEffect } from 'react'
const Test = () => {
const [count1, setCount1] = useState(0);
const [count2, setCount2] = useState(0);
useEffect(() => {
console.log('useEffect触发了')
});
return (
<>
<h1>count1:{count1}</h1>
<h1>count2:{count2}</h1>
<button onClick={() => setCount1(count1 + 1)}>count1+1</button>
<button onClick={() => setCount2(count2 + 1)}>count2+1</button>
</>
);
}
export default Test
将上述代码useEffect第二个参数传入需要绑定的状态,可绑定多个:
useEffect(() => {
console.log('useEffect触发了')
}, [count1]);
可以看到,只有绑定的count1发生变化才会触发,如果传空数组则任何状态发生变化都不会触发,此时useEffect的作用就类似class组件中的componentDidMount,所以发送请求通常也会在此执行。
在上面的操作中都不用清理的副作用,然而,有些副作用是需要去清理的,不清理会造成异常甚至内存泄漏,比如开启定时器,如果不清理,则会多次开启,从上面可以看到useEffect的第一个参数是一个回调函数,可以在回调函数中再返回一个函数,该函数可以在状态更新后第一个回调函数执行之前调用,具体实现:
seEffect(() => {
return () => {
}
});
高阶组件就是一个函数,接受一个组件作为参数,返回一个新的组件