react函数式组件基础入门学习,官网Hook 简介 – React
1. useState(保存组件状态)
const [state , setState] = useState(initialState)
todolist例子:
import React from 'react'
import { useState } from 'react'
export default function Todolist() {
// 声明叫 "text" ,"list"的 state 变量 useState(初始值)
const [text, setText] = useState("")
const [list, setList] = useState(['a', 'b', 'c'])
// setText setList 更新state
// !!!!在函数组件中没有this:!!!!
const handleChange = (evt) => {
setText(evt.target.value)
}
const handleClick = () => {
console.log(text);
setList([...list, text])
setText("")
}
const handleDel = (index) => {
console.log(index);
var newlist = [...list]
newlist.splice(index, 1)
setList(newlist) //获取删除后 新的list 并渲染
}
return (
<div>
<input onChange={handleChange} value={text} />
<button onClick={handleClick}>add</button>
<ul>
{
list.map((item, index) =>
<li key={index}>
{item}
<button onClick={() => handleDel(index)}>del</button>
</li>)
}
</ul>
{/* !list.length 数组长度不为0 */}
{!list.length && <div>暂无待办事项</div>}
</div>
)
}
useState函数用于更新 state。
useState的用法分别是声明、读取、使用(修改)。
useState返回值为:当前 state 以及更新 state 的函数。
2. useEffect(保存组件状态)
useEffect在组件mount时执行,但也会在组件更新时执行。
因为我们在每次请求数据之后都会设置本地的状态,所以组件会更新,因此useEffect会再次执行,因此出现了无限循环的情况。
我们只想在组件mount时请求数据。我们可以传递一个空数组作为useEffect的第二个参数,这样就能避免在组件更新执行useEffect,只会在组件mount时执行。
useEffect的第二个参数可用于定义其依赖的所有变量。如果其中一个变量发生变化,则useEffect会再次运行。如果包含变量的数组为空,则在更新组件时useEffect不会再执行,因为它不会监听任何变量的变更。
例子:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
function App() {
const [data, setData] = useState({ hits: [] });
// 用 async / await 来获取数据,按照标准 async 函数会返回一个隐式的 promise。
// 然而,effect hook 不能返回任何任何东西,也不能返回函数。
// 所以会报错: An effect function must not return anything besides a function, which is used for clean-up.
// 直接在 useEffect 里使用 async 函数是不允许的
// useEffect(async () => {
// const result = await axios(
// 'https://hn.algolia.com/api/v1/search?query=redux',
// );
// setData(result.data);
// });
// 正确写法
useEffect(() => {
const fetchData = async () => {
const result = await axios(
'https://hn.algolia.com/api/v1/search?query=redux',
);
setData(result.data);
};
fetchData();
}, []);
return (
<ul>
{data.hits.map(item => (
<li key={item.objectID}>
<a href={item.url}>{item.title}</a>
</li>
))}
</ul>
);
}
export default App;
3. useCallback(记忆函数)
useCallback 用于 缓存函数。它接受一个回调函数,和一个依赖项。
在组件第一次渲染时,useCallback 将传入的回调函数缓存起来。后面重新渲染时,如果依赖项没有发生更新,useCallback 会返回缓存的函数;如果依赖项更新了,就更新缓存。
4. useMemo记忆组件
useMemo常用在以下两种场景的优化中:1)引用类型的变量 2)需要大量时间执行的计算函数。
useCallback 的功能完全可以由useMemo取代。区别是:useCallback不会执行第一个参数函数,而是将它返回给你,而useMemo会执行第一个函数并且将函数执行结果返回给你
5. useRef (保存引用值) 官网描述:useRef hook
使用useRef后,有一个.current属性, 该属性不会引发组件重新渲染。
保持临时变量不丢失(引用的闭包原理);绑在dom或组件上方便实现组价通信和dom节点的访问
6.useContext (减少组件层级)
如果需要在组件之间共享状态,可以使用useContext()
const value = useContext(MyContext);