学习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也不会被再次执行了