摘要: React示例教程。html
- 原文:快速瞭解 React Hooks 原理
- 譯者:前端小智
到 React 16.8 目前爲止,若是編寫函數組件,而後遇到須要添加狀態的狀況,我們就必須將組件轉換爲類組件。前端
編寫 class Thing extends React.Component
,將函數體複製到render()
方法中,修復縮進,最後添加須要的狀態。react
今天,可使用 Hook 得到相同的功能,併爲本身節省了工做時間。在本文中,主要介紹useState
hook。編程
useState 作啥子的
useState
hook 容許我們向函數組件添加狀態,咱們一般稱這些爲「 hooks」,但它們其實是函數,與 React 16.8 捆綁在一塊兒。 經過在函數組件中調用useState
,就會建立一個單獨的狀態。小程序
在類組件中,state
老是一個對象,能夠在該對象上添加保存屬性。segmentfault
對於 hooks,state 沒必要是對象,它能夠是你想要的任何類型-數組、數字、布爾值、字符串等等。每次調用useState
都會建立一個state
塊,其中包含一個值。微信小程序
示例1:使用 useState 顯示/隱藏組件
這個示例是一個組件,它顯示一些文本,並在末尾顯示一個read more
連接,當單擊連接時,它展開剩下的文本。數組
import React, { useState } from 'react'; import ReactDOM from 'react-dom'; // 兩個 props: // text - 顯示的內容 // maxLength - 在點擊「read more」以前顯示多少個字符 function LessText({ text, maxLength }) { // 建立一個狀態,並將其初始化爲「true」 const [hidden, setHidden] = useState(true); if (text <= maxLength) { return <span>{text}</span>; } return ( <span> {hidden ? `${text.substr(0, maxLength).trim()} ...` : text} {hidden ? ( <a onClick={() => setHidden(false)}> read more</a> ) : ( <a onClick={() => setHidden(true)}> read less</a> )} </span> ); } ReactDOM.render( <LessText text={`專一、努力是成功的真正關鍵。把你的眼睛盯在目標上,而後朝着目標邁出下一步`} maxLength={35} />, document.querySelector('#root') );
僅用一行代碼,咱們就使這個函數組件有狀態:微信
const [hidden, setHidden] = useState(true);
可是這個函數到底在作什麼呢?若是每次渲染都調用它(確實如此),它又是如何保留狀態的。less
Hooks 實現的技巧
這裏的「神奇」之處是,React在每一個組件的幕後維護一個對象,而且在這個持久對象中,有一個「狀態單元」數組。當你調用useState
時,React
將該狀態存儲在下一個可用的單元格中,並遞增數組索引。
假設你的 hooks
老是以相同的順序調用(若是遵循 hooks 的規則,它們將是相同的順序),React可以查找特定useState
調用的前一個值。對useState
的第一個調用存儲在第一個數組元素中,第二個調用存儲在第二個元素中,依此類推。
這也不是很神奇的事情,主要它依賴於你可能沒有想過的事實:我們寫的的組件是由React
調用 ,因此它能夠在調用組件以前事先作好一些工做。 並且,渲染組件的行爲不只僅是函數調用。 像<Thing />
這樣的JSX
被編譯爲React.createElement(Thing)
- 顯然 React 能夠控制它的調用方式和時間。
示例2:根據以前的狀態更新狀態
看看另外一個例子:根據前一個值更新state
的值。
我們要造個計步器,每點擊一次按鈕,就計一次,點擊完後,它會告訴你你走了多少步。
import React, { useState } from 'react'; function StepTracker() { const [steps, setSteps] = useState(0); function increment() { setSteps(steps => steps + 1); } return ( <div> 總共走了 {steps} 步! <br /> <button onClick={increment}> 點點我,步數不是個事! </button> </div> ); } ReactDOM.render( <StepTracker />, document.querySelector('#root') );
首先,經過調用useState
建立一個新的state
,並將其初始化爲0
。它返回steps
的當前值0
和setSteps
函數來更新 steps
,用 increment
函數來對steps
進行增 1 操做。
這裏還能夠優化的提取increment
函數,能夠直接將 increment
函數裏面的內聯到 onClick
裏面:
<button onClick={() => setSteps(steps => steps + 1)}> I took another step </button>
示例3: state 做爲數組
記住,state
能夠保存任何你想要的值。下面是一個隨機數列表的例子,單擊按鈕將向列表添加一個新的隨機數:
function RandomList() { const [items, setItems] = useState([]); const addItem = () => { setItems([ ...items, { id: items.length, value: Math.random() * 100 } ]); }; return ( <> <button onClick={addItem}>Add a number</button> <ul> {items.map(item => ( <li key={item.id}>{item.value}</li> ))} </ul> </> ); }
注意,咱們state
初始化爲空數組[]
,並在addItem
函數中更新值。
setItems
更新 state
不會將舊值「合併」 - 它會使用新值覆蓋state
。 這與this.setState
在類中的工做方式不一樣。
示例4:具備多個鍵的 state
再來看看,state
爲對象的例子,建立一個包含2個字段的登陸表單:username
和password
。
下面示例主要展現如何在一個state
對象中存儲多個值,以及如何更新單個值。
function LoginForm() { const [form, setValues] = useState({ username: '', password: '' }); const printValues = e => { e.preventDefault(); console.log(form.username, form.password); }; const updateField = e => { setValues({ ...form, [e.target.name]: e.target.value }); }; return ( <form onSubmit={printValues}> <label> Username: <input value={form.username} name="username" onChange={updateField} /> </label> <br /> <label> Password: <input value={form.password} name="password" type="password" onChange={updateField} /> </label> <br /> <button>Submit</button> </form> ); }
若是想試試,可查看 CodeSandbox。
首先,咱們建立一個state
片斷,並用一個對象初始化它
const [form, setValues] = useState({ username: '', password: '' })
這看起來像是在類中初始化狀態的方式。
還有一個處理提交的函數,其中,e.preventDefault
來阻止頁面刷新並打印出表單值。
updateField
函數更有意思。它使用setValues
傳遞一個對象,爲了確保現有的狀態不被覆蓋,這裏使用了展開運算(...form
)。
代碼部署後可能存在的BUG無法實時知道,過後爲了解決這些BUG,花了大量的時間進行log 調試,這邊順便給你們推薦一個好用的BUG監控工具 Fundebug。
原文:https://daveceddia.com/usestate-hook-examples/
關於Fundebug
Fundebug專一於JavaScript、微信小程序、微信小遊戲、支付寶小程序、React Native、Node.js和Java線上應用實時BUG監控。 自從2016年雙十一正式上線,Fundebug累計處理了20億+錯誤事件,付費客戶有陽光保險、核桃編程、荔枝FM、掌門1對一、微脈、青團社等衆多品牌企業。歡迎你們免費試用!