使用场景
参数只会在组件的初始渲染中起作用,后续渲染时会被忽略。如果初始 state 需要通过计算才能获得,则可以传入一个函数,在函数中计算并返回初始的 state,此函数只在初始渲染时被调用
语法
const [name, setName] = useState(()=>{ // 编写计算逻辑 return '计算之后的初始值'})
语法规则
name
的初始值语法选择
useState(普通数据)
即可使用场景
在组件被销毁时,如果有些副作用操作需要被清理,就可以使用此语法,比如常见的定时器
语法及规则
useEffect(() => {
console.log('副作用函数执行了')
// 副作用函数的执行时机为: 在下一次副作用函数执行之前执行
return () => {
console.log('清理副作用的函数执行了')
// 在这里写清理副作用的代码
}
})
定时器小案例
添加副作用函数前:组件虽然已经不显示了,但是定时器依旧在运行
import { useEffect, useState } from 'react'
function Foo() {
useEffect(() => {
setInterval(() => {
console.log('副作用函数执行了')
}, 1000)
})
return <div>Foo</div>
}
function App() {
const [flag, setFlag] = useState(true)
return (
<>
<button onClick={() => setFlag(false)}>click</button>
{flag ? <Foo/> : null}
</>
)
}
export default App
添加清理副作用函数后:一旦组件被销毁,定时器也被清理
import { useEffect, useState } from 'react'
function Foo() {
useEffect(() => {
const timerId = setInterval(() => {
console.log('副作用函数执行了')
}, 1000)
// 添加清理副租用函数
return () => {
clearInterval(timerId)
}
})
return <div>Foo</div>
}
function App() {
const [flag, setFlag] = useState(true)
return (
<>
<button onClick={() => setFlag(false)}>click</button>
{flag ? <Foo/> : null}
</>
)
}
export default App
使用场景
如何在useEffect中发送网络请求,并且封装同步 async await操作
语法要求
不可以直接在useEffect的回调函数外层直接包裹 await ,因为**异步会导致清理函数无法立即返回
useEffect(async ()=>{
const res = await axios.get('http://xxxx')
console.log(res)
},[])
正确写法
在内部单独定义一个函数,然后把这个函数包装成同步
useEffect(()=>{
async function fetchData(){
const res = await axios.get('http://geek.itheima.net/v1_0/channels') console.log(res)
}
},[])
使用场景
在函数组件中获取真实的dom元素对象或者是组件对象
使用步骤
useRef
函数useRef
函数并传入null,返回值为一个对象 内部有一个current属性存放拿到的dom对象(组件实例)获取dom
import { useEffect, useRef } from 'react'
function App() {
const h1Ref = useRef(null)
useEffect(() => {
console.log(h1Ref)
},[])
return (
<div>
<h1 ref={ h1Ref }>this is h1</h1>
</div>
)
}
export default App
获取组件实例
函数组件由于没有实例,不能使用ref获取,如果想获取组件实例,必须是类组件
class Foo extends React.Component {
sayHi = () => {
console.log('say hi')
}
render(){
return <div>Foo</div>
}
}
export default Foo
import { useEffect, useRef } from 'react'
import Foo from './Foo'
function App() {
const h1Foo = useRef(null)
useEffect(() => {
console.log(h1Foo)
}, [])
return (
<div> <Foo ref={ h1Foo } /></div>
)
}
export default App
实现步骤
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