React Hooks就是加强版的函数组件,我们可以完全不使用 class,就能写出一个全功能的组件*
组件尽量写成纯函数,如果需要外部功能和副作用,就用钩子把外部代码"钩"进
四种最常用钩子
useState()
userContext()
userReducer()
useEffect()
不同的钩子为函数引入不同的外部功能,我们发现上面四种钩子都带有use前缀,React约定,钩子一律使用 use前缀命名。所以,你自己定义的钩子都要命名为useXXX。
userState():状态钩子
useState()用于为函数组件引入状态。
在组件里,useState你想用多少次,就用多少次:
import React, {useState} from 'react'
const AddCount = () => {
const [ count, setCount ] = useState(0)
const [age, setAge] = useState(25); //可以同上面同时存在
const addcount = () => {
let newCounts = count
setCount(newCounts+=1)
}
return (
<>
<p>{count}</p>
<button onClick={addcount}>count++</button>
</>
)
}
export default AddCount
useState() 函数为我们提供了两个东西:
- 一个保存状态值的变量,在本例中称为count;
- 一个更改值的函数,在本例中称为setCount。
const [count, setCount] = useState(0); //数组中的名字任意
useContext():共享状态钩子
在组件之间共享状态
import React,{ useContext } from 'react'
const useContextCe = () => {
const AppContext = React.createContext({})
const A =() => {
const { name } = useContext(AppContext)
return (
<p>A{name}<span>A子{name}</span></p>
)
}
const B =() => {
const { name } = useContext(AppContext)
return (
<p>B{name}</p>
)
}
return (
<AppContext.Provider value={{name: 'useContext'}}>
<A/>
<B/>
</AppContext.Provider>
)
}
export default useContextCe
useEffect():副作用钩子
组件的状态因为一些外界因素改变的时候,这就可以称作副作用。 组件中使用任意数量的Hooks,并根据需要混合使用
在默认情况下,useEffect Hook 在每次渲染和重新渲染时都会执行。 只要组件中的状态发生变化或组件收到新的props时,组件都会重新渲染并导致useEffect Hook 再次运行
useEffect(() => {},[array])
useEffect()接受两个参数,第一个参数是你要进行的异步操作,第二个参数是一个数组,用来给出Effect的依赖项。只要这个数组发生变化,useEffect()就会执行。当第二项省略不写时,useEffect()会在每次组件渲染时执行。这一点类似于类组件的`componentDidMount,此时 Hook 在挂载组件时仅运行一次 。函数组件没有生命周期函数,可用useEffect代替。
function Counter() {
const [count, setCount] = useState(0);
useEffect(() => {
const timer = setInterval(() => {
setCount(count => count + 1);
}, 1000);
return () => clearInterval(timer);
}, []);
return (
<>
Count: {count}
</>
);
}
useReducer():Action钩子
const [state, dispatch] = useReducer(reducer, initialState);
reducer函数和状态的初始值作为参数,返回一个数组,其中第一项为当前的状态值,第二项为发送action的dispatch函数
//官方示例
function countReducer(state, action) {
switch (action.type) {
case 'add':
return state + 1;
case 'minus':
return state - 1;
default:
return state;
}
}
function initFunc(initialCount) {
return initialCount + 1;
}
function Counter({initialCount = 0}) {
const [count, dispatch] = useReducer(countReducer, initialCount, initFunc);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => { dispatch({ type: 'add' }); }} >
+1
</button>
<button onClick={() => { dispatch({ type: 'minus' }); }} >
-1
</button>s
</div>
);
}
注:
useReducer无法为我们提供中间件等功能,加入你有这些需求,还是需要用到redux。