學習hooks
在 React 的世界中,
元件有函式元件和類元件
UI 元件我們可以使用函式,用函式元件來展示 UI。
而對於容器元件,函式元件就顯得無能為力。
我們依賴於類元件來獲取資料,處理資料。
React 在 v16.8 的版本中推出了 React Hooks 新特性。
以前我們更改資料都是通過setState。
現在我們可以使用 useState
在函式元件中用useState更改資料狀態
import { useState } from "react";
export default function Funcom() {
// setName可以去改變name的值
const [name, setName] = useState('紫川')
// 改變name的值
function changeValue() {
setName('今天在追劇,爽歪歪')
}
return (
<div>
<button onClick={changeValue}>改變值</button>
<div>顯示的值--{name}</div>
</div>
)
}
往陣列中新增一個值
import { useState } from "react";
export default function Funcom() {
// setName可以去改變name的值
const [list, setList] = useState([{ name: '紫川秀', id: 1 }, { name: '斯特林', id: 2 }])
let obj= {
name: '紫川-秀字營',
name2: '斯特林-哇哇'
}
// 改變name的值
function addHandler() {
// 新增值的方式,通過擴充套件你運算的方式,將新值進行追加
setList([...list, { name:'帝林',id:3 }] )
}
return (
<div>
<button onClick={addHandler}>新增值</button>
<ul>
{
list.map(item => <li key={item.id}> {item.name }</li>)
}
</ul>
</div>
)
}
做一個add del的小案例
import { useState } from "react";
export default function Funcom() {
const [list, setList] = useState([{ name: '紫川秀', id: 1 }, { name: '斯特林', id: 2 }])
let [text, setText] = useState('')
// 儲存使用者當前輸入的值
function changeValue(e) {
setText(e.target.value)
}
// 新增數值
function addHandler() {
setList([...list, { name: text, id: Math.random(0, 1000000000) }])
// 清空值,使用 value={ text}進行繫結就可以了
setText('')
}
// 刪除方法
function delHandler(index) {
let newlist = [...list]
newlist.splice(index, 1)
setList(newlist)
}
return (
<div>
<input type="text" onChange={changeValue} value={ text} />
<button onClick={addHandler}>新增值</button>
<ul>
{
list.map((item,index) => <li key={item.id}>
<span>{item.name}</span>
<button onClick={() => { delHandler(index)}}>刪除</button>
</li>)
}
</ul>
</div>
)
}
useEffect(處理副作用)和useLayoutEffect(同步執行副作用)
Function Component 不存在生命週期
所以不要把class Component的生命週期的概念搬過來對號入座
useEffect的簡單使用
import { useState } from "react";
import axios from 'axios'
export default function Funcom() {
const [list, setList] = useState([])
axios.get('https://edu.xxxx.cn/ccc.php').then(res => {
console.log(res.data)
let backArr =res&&res.data || []
setList(backArr)
})
return (
<div>
<ul>
{
list.map((item, index) => <li key={index}>
<span>{item.title}</span>
</li>)
}
</ul>
</div>
)
}
我們發現資料一直在跟新。程式碼一直在請求資料。
怎麼會這樣了?
我現在來說不清楚,那怎麼解決呢?
使用 useEffect
簡單使用 useEffect
import { useEffect, useState } from "react";
import axios from 'axios'
export default function Funcom() {
const [list, setList] = useState([])
// useEffect的第一個引數是一個函式,第二個是陣列。表示依賴的狀態,空陣列表示沒有依賴
// 這樣就不會一直執行了
useEffect(() => {
axios.get('https://edu.xxx.cn/zzzz.php').then(res => {
console.log(res.data)
let backArr = res && res.data || []
setList(backArr)
})
},[])
return (
<div>
<ul>
{
list.map((item, index) => <li key={index}>
<span>{item.title}</span>
</li>)
}
</ul>
</div>
)
}
useEffect依賴跟新
import { useEffect, useState } from "react";
export default function Funcom() {
const [name, setName] = useState('zhang')
useEffect(() => {
// 將首字母大寫
setName(name.substring(0,1).toUpperCase()+name.substring(1) )
}, [])
function changeValue() {
setName('xiaoming')
}
return (
<div>
<h2>姓名:{ name }</h2>
<button onClick={changeValue}>改變</button>
</div>
)
}
我們想的是 name的值發生改變後。
也會將 name.substring(0,1).toUpperCase()+name.substring(1)執行一次
但是實際上卻沒有,而是直接賦值了變成了 xiaoming
我們希望的是Xiaoming
使用依賴後
import { useEffect, useState } from "react";
export default function Funcom() {
const [name, setName] = useState('zhang')
// 第一次執行一次。 之後name(依賴)發生改變之後也會更新
useEffect(() => {
// 將首字母大寫
setName(name.substring(0,1).toUpperCase()+name.substring(1) )
//依賴的值name發生改變後, setName(name.substring(0,1).toUpperCase()+name.substring(1) )會又執行一次
}, [name])
function changeValue() {
setName('xiaoming')
}
return (
<div>
<h2>姓名:{ name }</h2>
<button onClick={changeValue}>改變</button>
</div>
)
}
不要對Dependencies撒謊
如果你使用了某個變數
卻沒有申明在依賴中
你等於向React撒了謊
之後的結果就是當依賴的變數改變的時候
useEffect也不會被再次執行了