摘要:前言樓主最近在整理的一些資料,為項目重構(gòu)作準備,下午整理成了這篇文章。給傳入的是一個初始值,比如,這個按鈕的最初要顯示的是。取代了提供了一個統(tǒng)一的。
Hooks are a new addition in React 16.8. They let you use state and other React features without writing a class.前言
樓主最近在整理 React Hooks 的一些資料,為項目重構(gòu)作準備,下午整理成了這篇文章。
如果之前沒接觸過相關(guān)概念,那么通過這篇文章, 你將會了什么是React Hooks , 它是做什么的 , 以及如何使用。
下面我會用一個具體的例子來說明, 通過這個例子, 你將了解:
如何使用 React Hooks
如何用 React Class components 實現(xiàn)同樣的邏輯
快速開始先快速搭建一個項目:
npx create-react-app exploring-hooksDemo in setState
import React, { Component } from "react"; export default class Button extends Component { state = { buttonText: "Click me, please" }; handleClick = () => { this.setState(() => { return { buttonText: "Thanks, been clicked!" }; }); }; render() { const { buttonText } = this.state; return ; } }
功能非常簡單: 點一下按鈕, 就更新 button 的 text。
Demo in Hooks這里,我們將不再使用 setState 和 ES6 Class. 輪到我們的Hooks登場了:
import React, { useState } from "react";
引入 useState 就意味著我們將要把一些狀態(tài)管理置于組件內(nèi)部, 而且我們的 React Component 將不再是一個 ES6 class, 取而代之的是一個簡單的純函數(shù)。
引入 useState 之后,我們將從中取出一個含有兩個元素的數(shù)組:
const [buttonText, setButtonText] = useState("Click me, please");
如果對這個語法有疑問, 可以參考 ES6 解構(gòu).
這兩個值的名字, 你可以隨意取, 和 React 無關(guān),但是還是建議你根據(jù)使用的目的取一個足夠具體和清晰的名字。
就比如上面寫的, 一個代表是 buttonText 的 值, 另一個代表是 setButtonText 的 更新函數(shù)。
給 useState 傳入的是一個初始值, 比如, 這個按鈕的最初要顯示的是: Click me, please。
這個簡單的例子的代碼全貌:
import React, { useState } from "react"; export default function Button() { const [buttonText, setButtonText] = useState("Click me, please"); function handleButtonClick() { return setButtonText("Thanks, been clicked!"); } return ; }
下面我們將介紹如何使用 Hooks 獲取數(shù)據(jù)。
使用 React Hooks 獲取數(shù)據(jù)在這之前, 我們都是在 componentDidMount 函數(shù)里調(diào)API:
import React, { Component } from "react"; export default class DataLoader extends Component { state = { data: [] }; async componentDidMount() { try { const response = await fetch(`https://api.coinmarketcap.com/v1/ticker/?limit=10`); if (!response.ok) { throw Error(response.statusText); } const json = await response.json(); this.setState({ data: json }); } catch (error) { console.log(error); } } render() { return (); } }{this.state.data.map(el => (
- {el.name}
))}
這種代碼大家想必都非常熟悉了, 下面我們用 Hooks 來重寫:
import React, { useState, useEffect } from "react"; export default function DataLoader() { const [data, setData] = useState([]); useEffect(() => { fetch("http://localhost:3001/links/") .then(response => response.json()) .then(data => setData(data)); }); return (); }{data.map(el => (
- {el.title}
))}
運行一下就會發(fā)現(xiàn),哎呦, 報錯了, 無限循環(huán):
原因其實也非常簡單, useEffect 存在的目的 和componentDidMount, componentDidUpdate, and componentWillUnmount是一致的, 每次state 變化 或者 有新的props 進來的時候,componentDidUpdate componentDidUpdate` 都會執(zhí)行。
要解決這個 "bug" 也非常簡單, 給 useEffect 傳入一個空數(shù)組作為第二個參數(shù):
useEffect(() => { fetch("http://localhost:3001/links/") .then(response => response.json()) .then(data => setData(data)); },[]); // << super important array
關(guān)于 Hook 的詳細信息可以參考: Using the Effect Hook
看到這你可能會按捺不住內(nèi)心的小火苗,要去重構(gòu)項目,個人還不建議這么做,因為接下來的幾個版本中可能會有變化, 就像Ryan Florence 建議的:
Hooks are not the endgame for React data loading.Data loading is probably the most common effect in an app.
Don"t be in a big hurry to migrate to hooks for data unless you"re okay migrating again when suspense for data is stable.
Own your churn.
— Ryan Florence (@ryanflorence) February 12, 2019
無論怎么說, useEffect 的出現(xiàn)還是一件好事。
能把 Hooks 用于 Render props 嗎能顯然是能的, 不過沒什么意義, 比如把上面的代碼改一下:
import React, { useState, useEffect } from "react"; export default function DataLoader(props) { const [data, setData] = useState([]); useEffect(() => { fetch("http://localhost:3001/links/") .then(response => response.json()) .then(data => setData(data)); }, []); return props.render(data) }
從外部傳入一個render即可, 但是這樣做毫無意義: Reack Hooks 本身就是為了解決組件間邏輯公用的問題的。
定義你的 React Hook還是上面的例子,我們把取數(shù)據(jù)的邏輯抽出來:
// useFetch.tsx import { useState, useEffect } from "react"; export default function useFetch(url) { const [data, setData] = useState([]); useEffect(() => { fetch(url) .then(response => response.json()) .then(data => setData(data)); }, [] ); return data; }
在其他組件中引用:
import React from "react"; import useFetch from "./useFetch"; export default function DataLoader(props) { const data = useFetch("http://localhost:3001/links/"); return (React Hooks 的本質(zhì)); }{data.map(el => (
- {el.title}
))}
上面我們說到 Reack Hooks 本身就是為了解決組件間邏輯公用的問題的。
回顧我們現(xiàn)在的做法,幾乎都是面向生命周期編程:
Hooks 的出現(xiàn)是把這種面向生命周期編程變成了面向業(yè)務(wù)邏輯編程,讓我們不用再去關(guān)注生命周期:
圖片來源
而且, 最新的React 中, 預(yù)置了大量的Hooks, 最重要兩個的就是: useState and useEffect.
useState 使我們在不借助 ES6 class 的前提下, 在組件內(nèi)部使用 state 成為可能。
useEffect 取代了 componentDidMount, componentDidUpdate, and componentWillUnmount, 提供了一個統(tǒng)一的API。
除了這兩個之外, 可以在官方文檔中了解更多:
一個顯而易見的事實是, 過不來了多久, 我們就會有三種創(chuàng)建React components 的姿勢:
functional components
class components
functional components with hooks
作為一個 React 忠實粉絲, 看到這些積極的變化實在是令人感到愉悅。
Hooks 更多學習資源還有很多幫助我們更好的學和掌握 React Hooks, 也在這里分享一下:
首先還是官方文檔: Introducing Hooks, Hooks at a Glance 是稍微深入一些的內(nèi)容。
然后是一個入門教程: Build a CRUD App in React with Hooks.
關(guān)于狀態(tài)管理, 還有一個比較有趣的文章: useReducer, don"t useState
比較有意思的是, 我們最后會大量使用 useReducer, 形勢和 Redux 非常類似:
function reducer(state, action) { const { past, future, present } = state switch (action.type) { case "UNDO": const previous = past[past.length - 1] const newPast = past.slice(0, past.length - 1) return { past: newPast, present: previous, future: [present, ...future], } case "REDO": const next = future[0] const newFuture = future.slice(1) return { past: [...past, present], present: next, future: newFuture, } default: return state } }
這也從側(cè)面證明了Redux 在社區(qū)中的影響力( 其實這兩個東西的核心開發(fā)者是同一個人 )。
總結(jié)Hooks 的出現(xiàn)簡化了邏輯,把面向生命周期編程變成了面向業(yè)務(wù)邏輯編程,為邏輯復用提供了更多可能。
Hooks 是未來的方向。
大概就是這些, 希望能對大家有些啟發(fā)和幫助。
才疏學淺,行文若有紕漏,還請各位大大幫忙指正, 謝謝。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/102583.html
摘要:前言樓主最近在整理的一些資料,為項目重構(gòu)作準備,下午整理成了這篇文章。給傳入的是一個初始值,比如,這個按鈕的最初要顯示的是。取代了提供了一個統(tǒng)一的。 showImg(https://segmentfault.com/img/bVbpUle?w=900&h=550); Hooks are a new addition in React 16.8. They let you use sta...
摘要:組件的職責增長并變得不可分割。是架構(gòu)的重要組成部分。有許多好處,但它們?yōu)槌鯇W者創(chuàng)造了入門的障礙。方法使用狀態(tài)鉤子的最好方法是對其進行解構(gòu)并設(shè)置原始值。第一個參數(shù)將用于存儲狀態(tài),第二個參數(shù)用于更新狀態(tài)。 學習目標 在本文結(jié)束時,您將能夠回答以下問題: 什么是 hooks? 如何使用hooks? 使用hooks的一些規(guī)則? 什么是custom hook(自定義鉤子)? 什么時候應(yīng)該使用 ...
摘要:由于其名氣和穩(wěn)定性獲得了廣泛好評。但是實際上在中并不是非常必要的。因此,這些結(jié)果也是純粹的速度實驗。它是否容易使用,開發(fā)過程是否令人愉快年和年的狀態(tài)報告顯示,和都享有良好的聲譽,大多數(shù)開發(fā)人員表示會再次使用。上手最簡單和最快的學習曲線。 翻譯:瘋狂的技術(shù)宅原文:https://www.toptal.com/react/... 本文首發(fā)微信公眾號:jingchengyideng歡迎關(guān)...
摘要:到目前為止,表達這種流程的基本形式是課程。按鈕依次響應(yīng)并更改獲取更新的文本。事實證明不能從返回一個??梢栽诮M件中使用本地狀態(tài),而無需使用類。替換了提供統(tǒng)一,和。另一方面,跟蹤中的狀態(tài)變化確實很難。 備注:為了保證的可讀性,本文采用意譯而非直譯。 在這個 React鉤子 教程中,你將學習如何使用 React鉤子,它們是什么,以及我們?yōu)槭裁催@樣做! showImg(https://segm...
摘要:當組件安裝和更新時,回調(diào)函數(shù)都會被調(diào)用。好在為我們提供了第二個參數(shù),如果第二個參數(shù)傳入一個數(shù)組,僅當重新渲染時數(shù)組中的值發(fā)生改變時,中的回調(diào)函數(shù)才會執(zhí)行。 前言 首先歡迎大家關(guān)注我的Github博客,也算是對我的一點鼓勵,畢竟寫東西沒法獲得變現(xiàn),能堅持下去也是靠的是自己的熱情和大家的鼓勵,希望大家多多關(guān)注呀!React 16.8中新增了Hooks特性,并且在React官方文檔中新增...
閱讀 1337·2021-11-22 09:34
閱讀 2201·2021-10-08 10:18
閱讀 1759·2021-09-29 09:35
閱讀 2496·2019-08-29 17:20
閱讀 2168·2019-08-29 15:36
閱讀 3428·2019-08-29 13:52
閱讀 811·2019-08-29 12:29
閱讀 1211·2019-08-28 18:10