目录
函数组件面临的问题
useEffect模拟函数组件的生命周期函数
其他生命周期函数
一、函数组件面临的问题
函数组件好是好,但是它有缺点。对比类组件,
它没有state和生命周期函数
。这样一来,许多细化的功能那不就不能使用函数组件了吗?
事实上并不是这样的,我们也可以使用 React 官方提供的 API 来模拟代替以上两个问题,接下来待我娓娓道来。
1、没有 state
- React V 16.8.0 推出的 Hooks API,其中 React.useState 可以解决问题。
- 详见:【React 全解 3 React.useState 原理详解】
2、没有生命周期函数
- React V 16.8.0 推出的 Hooks API,React.useEffect 可以模拟生命周期函数。
二、useEffect 模拟函数组件的生命周期函数
1、模拟 componentDidMount
useEffect(()=>{},[])
最主要的是第二个参数是空数组[],只会在组件挂载后运行一次。
/* 一个函数组件 */
const App = (props) => {
const [n, setN] = useState(0);
const click = () => {
setN(n + 1);
};
useEffect(() => {
console.log("模拟componentDidMount,即只运行一次该函数");
}, []);
return (
<div>
n:{n}
<button onClick={click}>n+1</button>
</div>
);
};
ReactDOM.render(<App />, document.getElementById("root"));
- 效果展示
- 可以看见,无论我点击多少次按钮使得 n,m 值发生变化,函数只触发一次,打印出一句话。
2、模拟 componentDidUpdate
useEffect(()=>{})或者useEffect(()=>{},[n])
第二个参数的含义解释:如果设置有多个 useState 的初始值,如有 n 和 m。那么,第二个参数不写,表示所有 state 值其中任意一个值变化了都会触发该函数,反而。只想要某个 state 值变化才触发函数,那么第二个参数的数组[]中必须加上要检测更新变化的 state 值。
所有的state任意一个更新触发函数
const App = () => {
const [n, setN] = React.useState(0);
const [m, setM] = React.useState(0);
useEffect(() => {
console.log("state变化了,无论n或者m");
});
return (
<div>
n:{n}
<button onClick={() => setN(n + 1)}>+1</button>
<hr />
m:{m}
<button onClick={() => setM(m + 1)}>+1</button>
<hr />
</div>
);
};
ReactDOM.render(<App />, document.getElementById("root"));
- 效果展示
- 可以看见,无论我点击多少次按钮使得 n,m 值发生变化,每点击一次都会触发函数,打印出一句话
只更新n值,当n值变化,才会触发函数(m值同理),在第二个参数的数组中加上n
const App = () => {
const [n, setN] = React.useState(0);
const [m, setM] = React.useState(0);
useEffect(() => {
console.log("n变化了");
}, [n]);
return (
<div>
n:{n}
<button onClick={() => setN(n + 1)}>+1</button>
<hr />
m:{m}
<button onClick={() => setM(m + 1)}>+1</button>
<hr />
</div>
);
};
ReactDOM.render(<App />, document.getElementById("root"));
- 效果展示
- 可以看见,无论我点击多少次按钮使得 n,m 值发生变化,只有点击 n 使 n 值发生变化,才会触发函数,打印出一句话。
3、模拟 componentWillUnMount
useEffect(()=>{console.log('渲染的时候执行'); return ()=>{console.log('组件要死了')}})
在 useEffect 的第一个参数为函数中 return 一个函数,表示组件将死。这个函数就是组件死之前可以执行的最后一次代码。而本身 useEffect 的第一个函数参数就是渲染的时候执行。
模拟组件将死
使用隐藏/显示组件的方式来模拟组件将死的情况。
const Test=()=>{
useEffect(()=>{
console.log('这是在渲染,只运行这一次');
return ()=>{
console.log('Test组件死了');
}
});
return (
<div>
Test组件
</div>
)
};
const App = () => {
const [isVisible, setIsVisible] = useState(true);
const hide = () => {
setIsVisible(false);
};
const show = () => {
setIsVisible(true);
};
return (
<div>
{ isVisible ?
<button onClick={hide}>hide</button>
:
<button onClick={show}>show</button>
}
{ isVisible? <Test />:null; }
</div>
);
};
效果展示
- 可以看见,每次点击按钮使得Test组件销毁和再生,它只会在销毁的时候执行return 的函数。
三、其他生命周期函数
1、constructor
- 函数组件创建执行时就相当于constructor
2、shouldComponentUpdate
- React.memo和useMemo可以解决,等后面文章整理详解。
3、render
- 函数组件的返回值就是render的返回值