函数组件
- 创建方式
- 没有state怎么办
- 没有生命周期怎么办
- useState原理
创建组件
const Hello = (props) => {
return <div>{props.message}</div>
}
const Hello = props => <div>{props.message}</div>
function Hello(props) {
return <div>{props.message}</div>
}
函数组件代替class组件
面临两个问题
- 函数组件没有state
- 函数组件没有生命周期
解决
没有state
- Hooks API中叫做useState可以解决问题
没有生命周期
- Hooks API叫做useEffect可以解决问题
函数组件实现一个+1功能
const App = props => {
const [n,setN] = useState(0)
const onClick = () => {
setN(n+1)
}
return (
<div>
{n}
<button onClick={onClick}>+1</button>
</div>
)
}
export default App;
用函数组件就简单很多,没有放出class组件实现的代码,而且函数组件消除了this
函数组件模拟生命周期
useEffect
模拟componentDidMount
useEffect(()=>{console.log('第一次渲染')},[])
模拟componentDidUpdate
useEffect(()=>{console.log('任意属性变更')})
useEffect(()=>{console.lod('n变了')},[n])
模拟componentWillUnmount
useEffect(()=>{console.log('第一次渲染') return ()=>{console('组件要死了')} })
后面的参数
[]
就是第一次调用[n]
就是n更新的时候执行,第一次也会执行[n,m]
就是n或者m变了就会执行,第一次也会执行- 如果是任何一个state(全部变量)变化都执行,那么
[参数]
整个这个东西就可以不写
函数组件的组合起来特别简单
const x = () => {
return <div>x</div>
}
const y = () => {
return <div>y</div>
}
const z = () => {
return <>
<x></x>
<y></y>
</>
}
函数组件写起来代码少,但是难一点
有一个问题
模拟componentDidUpdate
useEffect(()=>{console.lod('n变了')},[n])
在初始化的时候也会执行,那怎么才能在只有变化的时候才执行这个代码呢,就是第一次不执行
自定义hook
import React, {useState, useEffect } from "react";
const App = props => {
const [n, setN] = useState(0);
const onClick = () => {
setN(n+1);
};
const [nUpdateCount, setNUpdateCount] = useState(0)
useEffect(() => {
setNUpdateCount(x=>x+1)//这里x是接受的参数,就是nUpdateCount
}, [n])//n变了就把计数器加一
useEffect(()=>{
if(nUpdateCount > 1) {
console.log('n变了');
}
}, [nUpdateCount])//n变了,计数器就会变化,也就是相当于n变了
return (
<div>
{n}
<button onClick={onClick}>+1</button>
</div>
)
}
export default App;
这样就实现了这个功能
但是代码太杂了,我们可以封装一个函数
const useX = (n) => {
const [nUpdateCount, setNUpdateCount] = useState(0)
useEffect(() => {
setNUpdateCount(x=>x+1)//这里x是接受的参数,就是nUpdateCount
}, [n]);
return {
nUpdateCount: nUpdateCount
}
};
const nUpdateCount = useX(n).nUpdateCount
useEffect(()=>{
if(nUpdateCount > 1) {
console.log('n变了');
}
}, [nUpdateCount])
然后改成了这这样
再改
const useUpdate = (fn, dep) => {
const [Count, setCount] = useState(0)
useEffect(() => {
setCount(x=>x+1)
}, [dep]);
useEffect(()=>{
if(Count > 1) {
fn();
}
}, [Count, fn])
};
useUpdate(()=>{
console.log('n变了')
}, n)
就封装了一个函数useUpdate
,和useEffect
非常像
也可以直接拆分成一个组件,组件化
函数组件牛逼!!!