React Hooks入门

学习目标

在本文结束时,您将可以回答如下问题:react

  • 什么是 hooks?
  • 如何使用hooks?
  • 使用hooks的一些规则?
  • 什么是custom hook(自定义钩子)?
  • 何时应该使用 custom hooks?
  • 使用 custom hooks有什么好处?

什么是 hooks?

Hooks 能够作到如下事情:json

  • 在功能组件中使用state和“hook into”的生命周期方法。
  • 在组件之间重用有状态逻辑,这简化了组件逻辑,最重要的是,让你跳过编写classes。

若是你已经使用过React,你就会知道复杂多变,有状态的逻辑是如何获得的,当应用程序为功能添加了几个新功能时,就会发生组件代码变得复杂而难以维护这种状况。为了尝试简化这个问题,React背后的大脑试图找到解决这个问题的方法。数组

(1) 在组件之间重用有状态逻辑架构

hooks容许开发人员编写简单,有状态的功能组件,并在开发时花费更少的时间来设计和重构组件层次结构。怎么样?使用钩子,您能够在组件之间_获取_和_分享_有状态逻辑。框架

(2) 简化组件逻辑函数

当您的应用程序中出现不可避免的指数级逻辑增加时,简单的组件就回由于各类状态逻辑和生命周期等等因素,而变得繁琐和复杂。组件的职责增加并变得不可分割。反过来,这使编码变得麻烦而且测试困难。工具

class是React架构的重要组成部分。class有许多好处,但它们为初学者创造了入门的障碍。对于class,您还必须记住将this绑定到事件处理程序,所以代码可能变得冗长且有点多余。post

如何使用hooks?

React版本 16.8.学习

import { useState, useEffect } from 'react';

很简单,但你如何实际使用这些新方法?如下示例很是简单,但这些方法的功能很是强大。测试

useState hook方法

使用状态钩子(state hook)的最好方法是对其进行解构并设置原始值。第一个参数将用于存储状态,第二个参数用于更新状态。

例如:

const [weight, setWeight] = useState(150);
onClick={() => setWeight(weight + 15)}

weight是状态

setWeight是一种用于更新状态的方法

useState(150)是用于设置初始值(任何基本类型)的方法

值得注意的是,您能够在单个组件中屡次构造状态hook:

const [age, setAge] = useState(42);
const [month, setMonth] = useState('February');
const [todos, setTodos] = useState([{ text: 'Eat pie' }]);

所以,该组件可能看起来像:

import React, { useState } from 'react';
export default function App() {
  const [weight, setWeight] = useState(150);
const [age] = useState(42);
const [month] = useState('February');
const [todos] = useState([{ text: 'Eat pie' }]);
return (

      Current Weight: {weight}
      Age: {age}
      Month: {month}
       setWeight(weight + 15)}>
        {todos[0].text}


  );
}

useEffect钩子方法

使用effect hook 就好像使用componentDidMount, componentDidUpdate, 和 componentWillUnmount这类的生命周期的方法。

例如:

// similar to the componentDidMount and componentDidUpdate methods
useEffect(() => {
  document.title = You clicked ${count} times;
});

组件更新的任什么时候候,渲染后都会调用useEffect。如今,若是你只想在变量count改变时更新useEffect,你只需将该事实添加到数组中方法的末尾,相似于高阶reduce方法末尾的累加器。

// check out the variable count in the array at the end...
useEffect(() => {
  document.title = You clicked ${count} times;
}, [ count ]);

让咱们结合两个例子:

const [weight, setWeight] = useState(150);
useEffect(() => {
  document.title = You weigh ${weight}, you ok with that?;
}, [ weight ]);
onClick={() => setWeight(weight + 15)}

所以,当触发onClick时,也会调用useEffect方法,并在DOM更新后在文档标题中呈现新的数据。

例:

import React, { useState, useEffect } from 'react';
export default function App() {
  const [weight, setWeight] = useState(150);
const [age] = useState(42);
const [month] = useState('February');
const [todos] = useState([{ text: 'Eat pie' }]);
useEffect(() => {
    document.title = You weigh ${weight}, you ok with that?;
});
return (

      Current Weight: {weight}
      Age: {age}
      Month: {month}
       setWeight(weight + 15)}>
        {todos[0].text}


  );
}

useEffect很是适合进行API调用:

useEffect(() => {
  fetch('https://jsonplaceholder.typicode.com/todos/1')
    .then(results => results.json())
    .then((data) => { setTodos([{ text: data.title }]);
});
}, []);

React钩子看起来很棒,可是若是你花一点时间,你可能会意识到在多个组件中从新初始化多个钩子方法,好比useState和useEffect,可能会违背DRY(Don't repeat yourself)原则。那么,让咱们看看如何经过建立自定义钩子来重用这些新内置方法。

关于使用hooks的一些规则?

是的,React钩子有规则。这些规则乍一看彷佛是很是规的,可是一旦你理解了React钩子如何启动的基础知识,规则就很容易理解。

(1) 必须在顶层以相同的顺序调用挂钩。(依次调用)
Hooks建立一个钩子调用数组来保持秩序。这个命令有助于React告诉区别,例如,在单个组件中或跨应用程序的多个useState和useEffect方法调用之间。

例如:

// This is good!
function ComponentWithHooks() {
  // top-level!
  const [age, setAge] = useState(42);
const [month, setMonth] = useState('February');
const [todos, setTodos] = useState([{ text: 'Eat pie' }]);
return (
      //...
  )
}

在第一次渲染时,42,February,[{text:'Eat pie'}]都被推入状态数组。

当组件从新渲染时,忽略useState方法参数。

age,month和todos的值是从组件的状态中检索的,这是前面提到的状态数组。

(2) 没法在条件语句或循环中调用挂钩。
因为启动hooks的方式,不容许使用within条件语句或循环。对于hooks,若是在从新渲染期间初始化的顺序发生变化,则极可能您的应用程序没法正常运行。您仍然能够在组件中使用条件语句和循环,但不能在代码块内使用钩子。

例如:

// DON'T DO THIS!!
const [DNAMatch, setDNAMatch] = useState(false)

if (name) {
  setDNAMatch(true)
  const [name, setName] = useState(name)

  useEffect(function persistFamily() {
    localStorage.setItem('dad', name);
}, []);
}

// DO THIS!!
const [DNAMatch, setDNAMatch] = useState(false)
const [name, setName] = useState(null)

useEffect(() => {
  if (name) {
    setDNAMatch(true)
    setName(name)
    localStorage.setItem('dad', name);
}
}, []);

(3) 钩子不能用在class组件中。
钩子必须在功能组件或自定义钩子函数中初始化。自定义钩子函数只能在功能组件中调用,而且必须遵循与非自定义钩子相同的规则。

您仍然能够在同一个应用程序中使用类组件。您可使用hooks做为类组件的子项呈现功能组件。

(4) 自定义钩子应该以单词use开头而且是驼峰式的。
这是一个强有力的建议而非规则,但它将有助于您的应用程序的一致性。你也会知道,当你看到一个以“use”为前缀的函数时,它多是一个自定义钩子。

什么是自定义钩子?

自定义挂钩只是遵循与非自定义挂钩相同规则的函数。它们容许您整合逻辑,共享数据以及跨组件重用钩子。

何时应该使用自定义hook?

当您须要在组件之间共享逻辑时,最好使用自定义挂钩。在JavaScript中,当您想要在两个单独的函数之间共享逻辑时,您能够建立另外一个函数来支持它。好吧,就像组件同样,hooks也是function。您能够提取hooks逻辑,以便在应用程序的组件之间共享。在编写自定义hooks时,您能够命名它们(再次以“use”开头),设置参数,并告诉它们应该返回什么(若是有的话)。

例如:

import { useEffect, useState } from 'react';
const useFetch = ({ url, defaultData = null }) => {
  const [data, setData] = useState(defaultData);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
    fetch(url)
      .then(res => res.json())
      .then((res) => {
        setData(res);
setLoading(false);
})
      .catch((err) => {
        setError(err);
setLoading(false);
});
}, []);
const fetchResults = {
    data,
    loading,
    error,
  };
return fetchResults;
};
export default useFetch;

使用自定义hook有什么好处?

Hooks容许您在应用程序增加时抑制复杂性,并编写更易于理解的代码。下面的代码是两个具备相同功能的组件的比较。在第一次比较以后,咱们将在伴随容器的组件中使用自定义钩子展现更多好处。

如下类组件应该看起来:

import React from 'react';
class OneChanceButton extends React.Component {
  constructor(props) {
    super(props);
this.state = {
      clicked: false,
    };
this.handleClick = this.handleClick.bind(this);
}

  handleClick() {
    return this.setState({ clicked: true });
}

  render() {
    return (


          You Have One Chance to Click


    );
}
}

export default OneChanceButton;

如何使用钩子实现相同的功能来简化代码并提升可读性:

import React, { useState } from 'react';
function OneChanceButton(props) {
  const [clicked, setClicked] = useState(false);
function doClick() {
    return setClicked(true);
}

  return (


        You Have One Chance to Click


  );
}

export default OneChanceButton;

结论

React hooks是一个惊人的新功能!实施的理由是合理的;而且,再加上这一点,我相信这将极大地下降React编码的门槛,并使其保持在最喜欢的框架之上列表。看到这会如何改变第三方库的工做方式,尤为是状态管理工具和路由器,将会很是使人兴奋。

总之,React钩子:

  • 无需使用类组件便可轻松与React的生命周期方法相关联
  • 经过增长可重用性和抽象复杂性来帮助减小代码量
  • 帮助简化组件之间共享数据的方式
推荐阅读: https://juejin.im/post/5be8d3...
相关文章
相关标签/搜索