Hooks基本使用
useState
作用
useState为函数组件提供状态(state)
使用步骤
- 导入
useState函数 - 调用
useState函数,并传入状态的初始值 - 从
useState函数的返回值中,拿到状态和修改状态的方法 - 在JSX中展示状态
- 调用修改状态的方法更新状态
import { useState } from 'react'
function App() {
// 参数:状态初始值比如,传入 0 表示该状态的初始值为 0
// 返回值:数组,包含两个值:1 状态值(state) 2 修改该状态的函数(setState)
const [count, setCount] = useState(0)
return (
<button onClick={() => { setCount(count + 1) }}>{count}</button>
)
}
export default App
组件的更新过程
组件第一次渲染
- 从头开始执行该组件中的代码逻辑
- 调用
useState(0)将传入的参数作为状态初始值,即:0 - 渲染组件,此时,获取到的状态 count 值为: 0
组件第二次渲染
- 点击按钮,调用
setCount(count + 1)修改状态,因为状态发生改变,所以,该组件会重新渲染 - 组件重新渲染时,会再次执行该组件中的代码逻辑
- 再次调用
useState(0),此时 React 内部会拿到最新的状态值而非初始值,比如,该案例中最新的状态值为 1 - 再次渲染组件,此时,获取到的状态 count 值为:1
注意:useState 的初始值(参数)只会在组件第一次渲染时生效。也就是说,以后的每次渲染,useState 获取到都是最新的状态值,React 组件会记住每次最新的状态值
注意:useState 不能嵌套在if/for/其它函数中(react按照hooks的调用顺序识别每一个hook)
useState回调函数参数
// 回调函数中的逻辑只会在组件初始化的时候执行一次
const [name, setName] = useState(()=>{
// 编写计算逻辑 return '计算之后的初始值'
})
import { useState } from 'react'
function Counter(props) {
const [count, setCount] = useState(() => {
return props.count
})
return (
<div>
<button onClick={() => setCount(count + 1)}>{count}</button>
</div>
)
}
function App() {
return (
<>
<Counter count={10} />
<Counter count={20} />
</>
)
}
export default App
useEffect
作用
为react函数组件提供副作用处理的!
副作用是相对于主作用来说的,一个函数除了主作用,其他的作用就是副作用。对于 React 组件来说,主作用就是根据数据(state/props)渲染 UI,除此之外都是副作用(比如,手动修改 DOM)
常见副作用
- 数据请求 ajax发送
- 手动修改dom
- localstorage操作
使用步骤
- 导入
useEffect函数 - 调用
useEffect函数,并传入回调函数 - 在回调函数中编写副作用处理(dom操作)
- 修改数据状态
- 检测副作用是否生效
import { useEffect, useState } from 'react'
function App() {
const [count, setCount] = useState(0)
useEffect(()=>{
// dom操作
document.title = `当前已点击了${count}次`
})
return (
<button onClick={() => { setCount(count + 1) }}>{count}</button>
)
}
export default App
依赖项控制执行机制
// 组件首次渲染执行一次,不管是哪个状态更改引起组件更新时都会重新执行
useEffect(()=>{
console.log('副作用执行了')
})
// 组件只在首次渲染时执行一次
useEffect(()=>{
console.log('副作用执行了')
},[])
// 副作用函数在首次渲染时执行,在依赖项发生变化时重新执行
function App() {
const [count, setCount] = useState(0)
const [name, setName] = useState('zs')
useEffect(() => {
console.log('副作用执行了')
}, [count])
return (
<>
<button onClick={() => { setCount(count + 1) }}>{count}</button>
<button onClick={() => { setName('cp') }}>{name}</button>
</>
)
}
// 清理副作用 可以在副作用函数中的末尾return一个新的函数,在新的函数中编写清理副作用的逻辑
// 执行时机 1.组件卸载时自动执行 2.组件更新时,下一个useEffect副作用函数执行之前自动执行
import { useEffect, useState } from "react"
const App = () => {
const [count, setCount] = useState(0)
useEffect(() => {
const timerId = setInterval(() => {
setCount(count + 1)
}, 1000)
return () => {
// 用来清理副作用的事情
clearInterval(timerId)
}
}, [count])
return (
<div>
{count}
</div>
)
}
export default App
useEffect 发送网络请求
useEffect(()=>{
async function fetchData(){
const res = await axios.get('接口地址')
console.log(res)
}
},[])
useRef
作用
在函数组件中获取真实的dom元素对象或者是组件对象
使用步骤
- 导入
useRef函数 - 执行
useRef函数并传入null,返回值为一个对象 内部有一个current属性存放拿到的dom对象(组件实例) - 通过ref 绑定 要获取的元素或者组件
import { useEffect, useRef } from 'react'
function App() {
const h1Ref = useRef(null)
useEffect(() => {
console.log(h1Ref)
},[])
return (
<div>
<h1 ref={ h1Ref }>我是h1</h1>
</div>
)
}
export default App
useContext
作用
跨组件层级传递变量,实现数据共享
使用步骤
- 使用
createContext创建Context对象 - 在顶层组件通过
Provider提供数据 - 在底层组件通过
useContext函数获取数据
import { createContext, useContext } from 'react'
// 创建Context对象
const Context = createContext()
function Foo() {
return <div>Foo <Bar/></div>
}
function Bar() {
// 底层组件通过useContext函数获取数据
const name = useContext(Context)
return <div>Bar {name}</div>
}
function App() {
return (
// 顶层组件通过Provider 提供数据
<Context.Provider value={'this is name'}>
<div><Foo/></div>
</Context.Provider>
)
}
export default App