关于React Hooks,你不得不知的事

React Hooks是React 16.8发布以来最吸引人的特性之一。在开始介绍React Hooks之前,让咱们先来理解一下什么是hooks。wikipedia是这样给hook下定义的:

In computer programming, the term hooking covers a range of techniques used to alter or augment the behaviour of an operating system, of applications, or of other software components by intercepting function calls or messages or events passed between software components. Code that handles such intercepted function calls, events or messages is called a hook.

通俗来说,Hook(钩子)就是通过拦截软件和系统内部函数调用和消息通信来增强原有功能的技术。而React Hooks想要增强哪些功能呢?设想你的项目中已经有一大堆组件,这些组件各自都拥有自己的状态。那么一旦你想重用某些特定的带状态逻辑,就得大幅度重构你的应用。现在有了React Hooks,你只需要抽离这些带状态的逻辑代码,然后它们可以更好地进行重用, 而且独立出来的代码也更容易进行测试和管理。有了React Hooks后,你可以在函数式组件中实现之前在带状态组件中能做到的任何事,你能够更灵活地实现你的应用代码。

接下来,让我们看看React Hooks在实际项目中到底怎么使用。

状态管理

对于业务性组件来说,状态管理肯定是不可避免的。以前,我们通常写Class组件来管理业务逻辑,或者使用redux来全局管理状态。现在我们可以利用React Hooks新提供的State Hook来处理状态,针对那些已经写好的Class组件,我们也可以利用State Hook很好地进行重构, 先来看下面这段代码:

import React from 'react'; class Person extends React.Component { constructor(props) { super(props); this.state = { username: "scq000" }; } render() { return ( <div> <p>Welcome to homepage. {state.username}</p> <input type="text" placeholder="input a username" onChange={(event) => this.setState({ username: event.target.value)})}></input> </div> ); } } 复制代码

接下来尝试将它重构成函数式组件:

import React, {useState} from 'react'; export const Person = () => { const [state, setState] = useState({username: "scq000"}); return ( <div> <p>Welcome to homepage. {state.username}</p> <input type="text" placeholder="input a username" onChange={(event) => setState({username: event.target.value})}></input> </div> ) } 复制代码

如上面这段代码,我们首先使用useState api 来声明一个内部状态,接着声明一个新的状态变量state,以及它的setter方法。在这里,为了减少重构的工作量我特意选择了state这个变量名,你也可以单独将每个独立的状态提取出来使用, 比如使用代码const [username, setUsername] = userState("scq000")。在随后的组件内部,我们就可以利用这个内部状态来处理业务逻辑了。由于是函数式组件的写法,我们也能够避免很多this绑定,而且这部分逻辑在后续使用过程中也可以抽离出来进行重用。不过这里有个需要注意的点是:当你使用set方法的时候,旧状态不会自动merge到新状态中去,所以你如果提取的状态是个对象,且有多个属性时,需要使用如下语法进行状态的更新:

setState({ ...state, username: event.target.value }); 复制代码 生命周期管理

我们都知道,组件的生命周期管理是整个react组件的灵魂所在。利用生命周期函数,我们可以控制整个组件的加载、更新和卸载。React Hooks中提供了Effect钩子,使我们可以在函数式组件中实现这些功能。

为了便于理解,接下来我将分别演示如何利用Effect钩子实现原本在Class组件中的各个生命周期方法。下面这段代码是我们熟悉的Class组件:

import React from 'react'; class Person extends React.Component { constructor(props) { super(props); this.state = { username: "scq000" }; } componentDidMount() { console.log('componentDidMount: 组件加载后') } componentWillUnmount() { console.log('componentWillUnmount: 组件卸载, 做一些清理工作') } componentDidUpdate(prevProps, prevState) { if(prevState.username !== this.state.username) { console.log('componentDidUpdate: 更新usernmae') } } render() { return ( <div> <p>Welcome to homepage. {state.username}</p> <input type="text" placeholder="input a username" onChange={(event) => this.setState({ username: event.target.value)})}></input> </div> ); } } 复制代码

现在我们利用Effect重构一下:

import React, {useState, useEffect} from 'react'; export const Person = () => { const [state, setState] = useState({username: "scq000"}); useEffect(() => { console.log('componentDidMount: 组件加载后') return () => { console.log('componentWillUnmount: 组件卸载, 做一些清理工作') } }, []); useEffect(() => { console.log('componentDidUpdate: 更新usernmae') }, [state.username]); return ( <div> <p>Welcome to homepage. {state.username}</p> <input type="text" placeholder="input a username" onChange={(event) => setState({username: event.target.value})}></input> </div> ) } 复制代码

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwxxyg.html