1、回顾
2、Hook
react 16.8.0版本出现
它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。
(有状态使用class组件,无状态使用函数式组件)
函数式组件也可以写状态
Hook 使用了 JavaScript 的闭包机制
2.1 useState Hook ----- 函数式组件设置状态
import React, { useState } from 'react';
const Home = () => {
// 声明一个新的叫做 “count” 的 state 变量
// 设置初始化数据为0, 改变count的函数为setCount
const [ count, setCount ] = useState(0)
const [ list, setList ] = useState([1, 2, 3, 4])
return (
<div>
<button onClick= { () => {
let num = count + 1
setCount(num)
}}>加1</button>
{ count }
<button onClick= { () => {
setList([5,6,7,8])
}}>改变list</button>
{
list.map((item, index) => (
<p key = { index }> { item } </p>
))
}
</div>
)
}
export default Home;
2.2 useEffect
告诉 React 组件需要在渲染后执行某些操作。
React 会保存你传递的函数(我们将它称之为 “effect”),并且在执行 DOM 更新之后调用它。
import React, { useState, useEffect } from 'react';
import axios from 'axios';
// useEffect 其实是 componentDidMount + componentDidUpdate + componentWillUnmount
const Home = () => {
const [ bannerlist, setBannerlist ] = useState([])
useEffect(() => {
axios.get('/api/banner').then(res => {
setBannerlist(res.data.data)
// console.log(bannerlist)
})
})
const [ prolist, setProlist ] = useState([])
useEffect(() => {
axios.get('/api/pro').then(res => {
setProlist(res.data.data)
})
})
return (
<div>
轮播图列表
{
bannerlist.map(item => (
<p key = { item.bannerid }>
{ item.img }
</p>
))
}
{
prolist.map(item => (
<p key = { item.proid }>
{ item.proname }
</p>
))
}
</div>
)
}
export default Home;
2.3 控制effect每次执行
useEffect(() => {}, [count])
useEffect(() => {}, [])
2.4 Hook规则
只在最顶层使用 Hook
只在 React 函数中调用 Hook
ESLint 插件
import React, { useState, useEffect } from 'react';
import axios from 'axios';
// 自定义HOOK
const useLoginState = () => {
const [loginstate, setLoginstat] = useState('no')
useEffect(() => {
if (localStorage.getItem('loginstate') === 'ok') {
setLoginstat('ok')
} else {
setLoginstat('no')
}
}, [loginstate])
return loginstate
}
const Home = () => {
const loginstate = useLoginState()
return (
<div>
自定义HOOK
{
loginstate === 'ok' ? <p>登陆了</p> : <p>未登录</p>
}
</div>
)
}
export default Home;