Hooks是什么
官方文档很简单的介绍,可以不使用class来实现有状态的组件
为什么要引入Hooks
- 组件之间难以重用有状态的逻辑
虽然可以使用 render props 或者高阶组件来解决组件的重用问题,但是使用的时候我们需要把组件重构,这样会导致代码太笨重。如果使用太多的HOC会导致组件的层次结构很深。 https://github.com/facebook/react-devtools/pull/503,使用Hooks就可以从组件中提取有状态逻辑,以便对其进行独立测试并重用。Hooks允许我们在不更改组件层次结构的情况下重用有状态逻辑
- 逻辑复杂的组件难以开发与维护,当我们的组件需要处理多个互不相关的 localstate 时,每个生命周期函数中可能会包含着各种互不相关的逻辑在里面
Hooks的种类
Hooks的分类有三种,分别是
- State Hook,定义state和setState方法
- Effect Hook,通过此Hooks操作获取数据的方法,可以看做是
componentDidMount
,componentDidUpdate
,componentWillUnmont
的合并 - Custom Hooks,自定义Hooks可以将组件逻辑提取到可重用函数中,使用use开头
State Hook
一个简单的栗子,声明一个Counter
组件并使用useState
来声明count
状态和setCount
函数,这里使用了数组的解构
第二个参数
setCount
可以使用任意的函数名,不一定是setCount
,可以是setNumber
,setSum
...,为了规范一点使用setCount
function Counter(props) {
// 声明一个 count 状态和 setCount 函数,useState(0) 参数表示默认值
const [count, setCount] = useState(0)
useEffect(() => {
console.log(`mount didmount unmount and count = ${count}`)
return () => {
console.log('component unmount')
}
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
)
}
接下来使用这个组件
class App extends Component {
render() {
return (
<div>
{ Counter() }
</div>
)
}
}
纳尼,报错了 Hooks can only be called inside the body of a function component. (https://fb.me/react-invalid-hook-call)
意思是Hooks只能在函数组件使用,不能在class组件使用
ReactDOM.render(<Counter name="aa"/>, document.getElementById('root'));
Effect Hook
Effect Hook也就是一个集成了componentDidMount
,componentDidUpdate
,componentWillUnmont功能的函数
上面的栗子引入了State Hook
,接下来引入Effect Hook到栗子 🍆中
function Counter() {
// 声明一个 count 状态和 setCount 函数,useState(0) 参数表示默认值
const [count, setCount] = useState(0)
useEffect(() => {
console.log(`mount didmount unmount and count = ${count}`)
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
)
}
可以看到挂载和click的时候会触发useEffect
函数
自定义Hook
自定义Hook就是以use
开头定义的javascript函数,比如在定义函数的时候,我们会把一些相同的逻辑封装成一个第三方函数,然后分别在其他函数使用,自定义Hook也是这个思想
举个栗子 🍆,我们需要在不同组件共享用户的登录状态,我们可以这样做
function useUserStatus(id) {
const [isLogin, setLogin] = useState(false)
useEffect(() => {
setLogin(id === 1)
})
return isLogin
}
function LoginBar() {
const isLogin = useUserStatus(1)
return (
<div>Login bar component { isLogin ? '已登陆' : '未登陆' }</div>
)
}
function App() {
const isLogin = useUserStatus(1)
return (
<div>
App component { isLogin ? '已登陆' : '未登陆' }
<LoginBar/>
</div>
)
}
Hooks规则
必须要在顶层使用Hooks,不要在循环,条件,嵌套函数使用Hooks
只从React函数调用Hooks,不要在js函数调用Hooks
总结
Hooks其实就是以函数的思想来写类组件,不同的Hooks可以通过参数传递