React的新特性之Hook

Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。

Hook的含义:

Hook 这个单词的意思是"钩子"。
React Hooks 的意思是,组件尽量写成纯函数,如果需要外部功能和副作用,就用钩子把外部代码"钩"进来。 React Hooks 就是那些钩子。

你需要什么功能,就使用什么钩子。React 默认提供了一些常用钩子,你也可以封装自己的钩子。

所有的钩子都是为函数引入外部功能,所以 React 约定,钩子一律使用use前缀命名,便于识别。你要使用 xxx 功能,钩子就命名为 usexxx。

Hook的优点

  • 可以在不改变组件层级关系的前提下,方便的重用带状态的逻辑。
  • 可以封装相关联的业务逻辑,让代码结构更加清晰。
  • 可以在不引入 Class 的前提下,使用 React 的各种特性。

Hook规则

  • 只在最顶层使用 Hook
  • 只在 React 函数中调用 Hook

State Hook

useState()用于为函数组件引入状态(state)。纯函数不能有状态,所以把状态放在钩子里面。

import React, { useState } from 'react';

function Count() {
  // 声明一个叫 “count” 的 state 变量。
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

上面代码中,Count组件是一个函数,内部使用useState()钩子引入状态。
useState()这个函数接受状态的初始值,作为参数,上例的初始值为0。该函数返回一个数组,数组的第一个成员是一个变量(示例代码中是count),指向状态的当前值。第二个成员是一个函数,用来更新状态,约定是set前缀加上状态的变量名(示例代码中是setCount)。

Effect Hook

useEffect()用来引入具有副作用的操作,最常见的就是向服务器请求数据。以前,放在componentDidMount里面的代码,现在可以放在useEffect()。
useEffect()的用法如下。

useEffect(()=>{ 
	//一些操作
},[dependencies]) 

useEffect()接受两个参数。第一个参数是一个函数,异步操作的代码放在里面。第二个参数是一个数组,用于给出 Effect 的依赖项,只要这个数组发生变化,useEffect()就会执行。第二个参数可以省略,这时每次组件渲染时,就会执行useEffect()。

import React, { useState, useEffect } from 'react';

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

  // Similar to componentDidMount and componentDidUpdate:
  useEffect(() => {
    // Update the document title using the browser API
    document.title = `You clicked ${count} times`;
  });

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

Context Hook

如果需要在组件之间共享状态,可以使用useContext()。
现在有两个组件 One和 Two,我们希望它们之间共享状态。首先使用 React Context API,在组件外部建立一个 Context。

const AppContext = React.createContext({});

<div className="Root">
	<One/>
	<Two/>
<div>

上面代码中,AppContext.Provider提供了一个 Context 对象,这个对象可以被子组件共享。
One 组件的代码如下:

const One =()=>{  
const { username }=useContext(AppContext);
return(
	<div>
		<p>我是第一个页面</p>
		<p>{username}</p>
	</div>
	);
}

上面代码中,useContext()钩子函数用来引入 Context 对象,从中获取username属性。
Two 组件的代码也类似:

const Two=()=>{  
const { username }=useContext(AppContext)
return(
		<div>
			<h1>Two</h1>
			<p>我是第二个页面</p>
			<p>{username}</p>
		</div>
	);
}

自定义Hook

通过自定义 Hook,可以将组件逻辑提取到可重用的函数中。自定义 Hook 是一个函数,其名称以 “use” 开头,函数内部可以调用其他的 Hook。
示例:

import { useState, useEffect } from 'react';

function useFriendStatus(friendID) {
  const [isOnline, setIsOnline] = useState(null);

  useEffect(() => {
    function handleStatusChange(status) {
      setIsOnline(status.isOnline);
    }

    ChatAPI.subscribeToFriendStatus(friendID, handleStatusChange);
    return () => {
      ChatAPI.unsubscribeFromFriendStatus(friendID, handleStatusChange);
    };
  });

  return isOnline;
}

useFriendStatus 的 Hook 目的是订阅某个好友的在线状态。这就是我们需要将 friendID 作为参数,并返回这位好友的在线状态的原因。

你可能感兴趣的:(react)