如今用react开发,绝大多数人肯定用hook来写业务了,我们需要在组件渲染的不同阶段执行一些业务逻辑,这就需要使用类组件的生命周期钩子。那么传统的class组件生命周期怎么用hook来模拟呢?
概要
| class组件 | function组件 |
|---|---|
| constructor | useState |
| getDerivedStateFromProps | 更新useState里面的update函数 |
| shouldComponentUpdate | React.memo |
| render | 函数本身 |
| componentDidMount | useEffect |
| componentDidUpdate | useEffect |
| componentWillUnmount | useEffect里面返回的函数 |
| componentDidCatch | 无 |
| getDerivedStateFromError | 无 |
关于useEffect中的参数问题
useEffect拥有两个参数,第一个参数作为回调函数会在浏览器布局和绘制完成后调用,因此它不会阻碍浏览器的渲染过程;第二个参数是一个数组。
下面是第二个参数的说明
- 当数组存在并有值时,如果数组中的任何值发生更改,则每次渲染后都会触发回调;
- 当它不存在时,每次渲染都会触发回调;
- 当它是一个空列表时,回调只会被触发一次,类似于componentDidMount;
具体演示
constructor
class foo extends Component {
constructor() {
super();
this.state = {
num: 0
}
}
render() {
return <div>{this.state.num}</div>;
}
}
function foo() {
const [num, setNum] = useState(0)
return <div>{num}</div>
}
componentDidMount
class foo extends React.Component {
componentDidMount() {
console.log(`componentDidMount`);
}
render() {
return null
}
}
function foo() {
useEffect(() => {
console.log('componentDidMount');
}, [])
return null;
}
shouldComponentUpdate
shouldComponentUpdate(nextProps, nextState) {
console.log(`shouldComponentUpdate`);
//更新组件
return true
//不更新组件
// return false
}
const MemoComponent = React.memo(
HeaderComponent,
(prevProps, nextProps) => nextProps.count !== prevProps.count
)
componentDidUpdate
componentDidUpdate(props, state, snapshot) {
console.log(`mounted or updated`);
}
useEffect(() => {
console.log(`mounted or updated`);
})
//如果只想模拟componentDidUpdate,不在组件首次创建时调用,可以使用useRef
const mounted = useRef();
useEffect(() => {
if (!mounted.current) {
mounted.current = true;
} else {
console.log('didUpdate');
}
})
//useRef在组件中创建‘实例变量’。作为标志指示组件是否处于挂载或更新阶段。当组件更新完成后会执行else里面的内容,以此来单独模拟componentDidUpdate。
componentWillUnmount
componentWillMount() {
console.log(`componentWillUnmount`);
}
useEffect(() => {
return () => {
console.log(`wilUnmount`);
}
}, [])
记录记录!