此名字暂不可见
No distraction,it's you and me

react Hooks

2024-12-16

react hooks

1.什么是Hooks

​ Hook是一些让你在不使用class的情况下使用state以及其他的react特性的函数。它允许你在函数组件里“钩入”React state等特性。不过,Hook不能再class中使用–你也没必要再使用class。

2.为什么要使用Hooks

  • Hook允许你在非class的情况下使用更多的React特性。
  • Hook使你在无需修改组件结构的情况下复用状态逻辑。
  • Hook将组件中相互关联的部分拆分成更小的函数。

3.一些常见的函数

1.useState

​ 在useState()中,它接受状态的初始值作为参数,并返回一个数组,其中数组的第一项为一个变量,指向状态的当前值,类似于this.state;第二项是一个函数,用来更新状态,类似于setState。

1
2
3
4
5
6
7
8
9
10
11
12
13
import { useState } from 'react'


function Example(){
const [count,setCount] = useState(0)

return(
<div>
<p>你一共点击了{count}下</p>
<button onClick={() => setCount(count + 1)}>点我</button>
</div>
)
}

2.useContext

​ useContext()用于在函数组件中订阅React的上下文。它允许你通过Context.Provider提供的共享数据。说人话,useContext让你能够在组件树中任何位置直接获取上下文数据,而不必通过props一层一层传递。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import { useContext } from 'react'

const Context = createContext('false')
function App(){
const [answer,setAnswer] = useState('false')

return(
<Context.Provider value={answer}>
<div>
<button onClick={() => setAnswer(true)}>点我就对了</button>
<Example />
</div>
</Context.Provider>
)
}

function Example(){
const answer = useContext(Context)

return(
<p>我对了吗?{answer}</p>
)
}


  • 首先,你需要使用createContext创建一个上下文对象,这里创建了Context,并提供了默认值’false‘

  • Context.Provider在组件树中提供了answer的数据。

  • Example组件通过useContext订阅了Context,并访问当前的answer值。

其中,Context.Provider是上下文系统的核心组件,它用于提供数据给组件树中的下游组件。它接受一个value属性,所有在其内部的组件都能访问到这个value,即使他们不是直接的父子关系。顺带一提,你可以在组件多次调用useContext来访问不同的上下值。

3.useEffect

​ useEffect()用于处理副作用操作。副作用是指组件渲染过程中,可能会对外部环境产生影响的操作,比如数据获取,订阅事件,操作DOM等。

​ 其中,useEffect接受两个参数,一个是副作用函数,另一个是依赖数组。

1
2
3
4
5
6
7
8
9
10
11
12
import { useEffect } from 'react'
import{ useState } from 'react'

function Example(){
const [count,setCount] = useState(0)

useEffect(() => {
setCount(count + 1)
})
}


当没有依赖数组时,useEffect会在组件首次渲染或组件更新时执行。

1
2
3
4
5
6
7
8
9
10
import { useEffect } from 'react'
import{ useState } from 'react'

function Example(){
const [count,setCount] = useState(0)

useEffect(() => {
setCount(count + 1)
},[])
}

当传入了空的依赖数组时,useEffect只会在组件首次渲染时执行一次。

1
2
3
4
5
6
7
8
9
10
import { useEffect } from 'react'
import{ useState } from 'react'

function Example(){
const [count,setCount] = useState(0)

useEffect(() => {
setCount(count + 1)
},[count])
}

当依赖数组中的值存在时,useEffect会在组件首次渲染和依赖数组中的值发生变化时执行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import { useEffect } from 'react

function Example(){
useEffect(() => {
const timer = setInterval(() => {
console.log('wuhu')
},1000);

return() =>{
clearInterval(timer)
}
},[])
}



useEffect可以返回一个清除函数,用于在卸载组件时清除副作用操作,比如取消订阅,清除定时器等。

4.useReducer

​ useReducer相当于是useState的进阶版。他接受一个形如(state,action)=> newState的reducer,并返回当前的state以及预期般配的dispatch方法。

1
const [state,dispatch] = useReducer(reducer,initialArg,init);

​ useReducer接受三个参数:

  • reducer
  • 初始化的state。如果没有第三个参数,则state默认是传入的值,返回值为最新的state和dispatch函数。
  • 对初始值state进行一个计算(可以没有)

​ useReducer和useState各有千秋,但在state逻辑较复杂且包含多个子值,或者下一个state依赖于之前的state等,useReducer回避useState更加适用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import { useReducer } from 'react'

const initialState = {count: 0};

const reducer =(state,action) => {
switch(action.type){
case'increment':
return{count:state.count + 1};
case'decrement':
return{count:state.count - 1};
default:
throw new Error();
}
}

function Example(){
const [state,dispatch] = useReducer(reducer,initialState);
return (
<>
Count:{state.count}
<button onClick={() => dispatch({type:'increment'})}>+</button>
<button onClick={() => dispatch({type:'decrement'})}>-</button>
</>
)
}

5.useRef

​ useRef()主要用于引用DOM原酸或存储一个可变的值,这个值在整个组件的声明周期保持不变。

  • useRef返回一个可变的ref对象,其内部只有一个current属性被初始化为传入的参数。
  • useRef返回的ref对象在组件的整个生命周期存在。
  • 更新current的值并不会触发页面的重新渲染。
  • useRef每次渲染时返回一个ref对象。

5.1引用DOM元素

1
2
3
4
5
6
7
8
9
10
11
12
import { useRef,useEffect } from 'react'

function inputFocus(){
const inputRef = useRef(null)

useEffect(() => {
inputRef.current.focus()
},[])

return<input ref={inputRef} />
}

inputRef是一个ref对象,它的current属性在组件首次渲染时设置为null,在组件被挂载时,inputRefer.current指向实际的inputDOM元素。

5.2存储一个可变的值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import {useRef,useState} from 'react'

function Example(){
const renderCount = useRef(0)
const [count,setCount] = useState(0)

const increment= () => {
setCount(count + 1)
renderCount.current++
}

return(
<div>
<p>Render Count: {renderCount.current}</p>
<p>Count: {count}</p>
<button onClick={increment}>+</button>
</div>
)
}

renderCount是一个ref对象,用来存储渲染次数。每次点击按钮时,increment函数会被调用,count和renderCount的值都会增加。但是,只有count状态的改变会触发组件重新渲染,renderCount.current则不会。

Author: John Doe

Link: https://159357254680.github.io/2024/12/16/react%20Hooks/

Copyright: All articles in this blog are licensed under CC BY-NC-SA 3.0 unless stating additionally.

< PreviousPost
作用域链与执行上下文
NextPost >
硬绑定方法
CATALOG
  1. 1. react hooks
    1. 1.1. 1.什么是Hooks
    2. 1.2. 2.为什么要使用Hooks
    3. 1.3. 3.一些常见的函数
      1. 1.3.1. 1.useState
      2. 1.3.2. 2.useContext
      3. 1.3.3. 3.useEffect
      4. 1.3.4. 4.useReducer
      5. 1.3.5. 5.useRef
        1. 1.3.5.1. 5.1引用DOM元素
        2. 1.3.5.2. 5.2存储一个可变的值