一些常用的react hooks以及各自的作用
一些常用的react hooks以及各自的作用
- 一、React Hooks是什么
- 二、一些常用的Hooks以及各自的作用
- 1、useState
- 2、useEffect
- 3、useContext
- 4、useMemo
- 5、useCallback
- 6、useReducer
- 7、useRef
一、React Hooks是什么
Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性
至于为什么引入hook,官方给出的动机是解决长时间使用和维护react过程中常遇到的问题,例如:
- 难以重用和共享组件中的与状态相关的逻辑
- 逻辑复杂的组件难以开发与维护,当我们的组件需要处理多个互不相关的 local state 时,每个生命* 周期函数中可能会包含着各种互不相关的逻辑在里面
- 类组件中的this增加学习成本,类组件在基于现有工具的优化上存在些许问题
- 由于业务变动,函数组件不得不改为类组件等等
在以前,函数组件也被称为无状态的组件,只负责渲染的一些工作
因此,现在的函数组件也可以是有状态的组件,内部也可以维护自身的状态以及做一些逻辑方面的处理
二、一些常用的Hooks以及各自的作用
1、useState
创建数据状态,方法里的参数为state默认的值,返回值是一个数组,第一个值为当前的state,第二个值为更新state的函数
import React, { useState } from 'react';
function Example() {
// 声明一个叫 "count" 的 state 变量
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p >
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
2、useEffect
可以进行带有副作用的操作,useEffect第一个参数接受一个回调函数,第二个参数是一个数组,数组元素指定特定值是否在两次渲染中发生变化,没有变化则跳过effect的调用
import { useEffect, useState } from "react";
export default function App() {
const [count, setCount] = useState(0)
const handleIncrement = () => setCount(count + 1)
const handleDecrement = () => setCount(count - 1)
useEffect(() => {
console.log('useEffect');
}, [count])
return (
<div style={{ padding: 10 }}>
<button onClick={handleIncrement}>+</button>
<span>{count}</span>
<button onClick={handleDecrement}>-</button>
</div>
);
}
3、useContext
用作组件通信
import { createContext, useContext } from "react";
export function Section({ children }) {
const level = useContext(LevelContext);
return (
<section className="section">
<LevelContext.Provider value={level + 1}>{children}</LevelContext.Provider>
</section>
);
}
export function Heading({ children }) {
const level = useContext(LevelContext);
switch (level) {
case 1:
return <h1>{children}</h1>;
case 2:
return <h2>{children}</h2>;
case 3:
return <h3>{children}</h3>;
case 4:
return <h4>{children}</h4>;
case 5:
return <h5>{children}</h5>;
case 6:
return <h1>{children}</h1>;
default:
throw Error("未知的 level: " + level);
}
}
const LevelContext = createContext(0);
export default function App() {
return (
<div>
<Section>
<Heading>主标题</Heading>
<Section>
<Heading>副标题</Heading>
<Heading>副标题</Heading>
<Heading>副标题</Heading>
<Section>
<Heading>子标题</Heading>
<Heading>子标题</Heading>
<Heading>子标题</Heading>
<Section>
<Heading>子子标题</Heading>
<Heading>子子标题</Heading>
<Heading>子子标题</Heading>
</Section>
</Section>
</Section>
</Section>
</div>
);
}
4、useMemo
用作数据缓存
import { useMemo, useState } from "react";
function DoSomeMath({value}){
const result = useMemo(() => {
console.log('DoSomeMath执行了');
let result = 0
for(let i = 0; i < 1000000; i++){
result += value * 2
}
return result
}, [value])
return (
<div>
<p>输入内容:{value}</p>
<p>经过复杂计算的数据:{result}</p>
</div>
)
}
export default function App() {
const [inputValue, setInputValue] = useState(5)
const [count, setCount] = useState(0)
return (
<div>
<p>count的值为:{count}</p>
<button onClick={() => setCount(count + 1)}>
点击更新
</button>
<br/>
<br/>
<input
type="number"
value={inputValue}
onChange={(e) => setInputValue(parseInt(e.target.value))}
/>
<DoSomeMath value={inputValue}/>
</div>
);
}
5、useCallback
用作函数缓存
import { memo, useCallback, useState } from "react";
// memo将组件变更为一个记忆组件,如果向这个组件传入的prop没有出现变话,它就不会受到父组件更新的影响
const Button = memo(function ({ onClick }) {
console.log("Button渲染了");
return <button onClick={onClick}>子组件</button>;
});
export default function App() {
const [count, setCount] = useState(0)
const handleClick = useCallback(() => {
console.log("点击按钮");
}, []);
const handleUpdate = () => {
setCount(count + 1)
}
return (
<div>
<p>Count:{count}</p>
<button onClick={handleUpdate}>点击</button>
<br />
<Button onClick={handleClick} />
</div>
);
}
6、useReducer
用作state的统一管理状态,可用useState代替
import { useReducer } from "react";
function countReducer(state, action){
switch (action.type){
case "increment":
return state + 1
case "decrement":
return state - 1
default:
throw new Error()
}
}
export default function App(){
// 计数器
// const [count, setCount] = useState(0)
// const handleIncrement = () => setCount(count + 1)
// const handleDecrement = () => setCount(count - 1)
const [state, dispatch] = useReducer(countReducer, 0);
const handleIncrement = () => dispatch({ type: "increment" });
const handleDecrement = () => dispatch({ type: "decrement" });
return (
<div style={{ padding: 10 }}>
<button onClick={handleIncrement}>+</button>
{/* <span>{count}</span> */}
<span>{state}</span>
<button onClick={handleDecrement}>-</button>
</div>
);
}
7、useRef
用作获取DOM结构和引用之前的状态值
// react hooks,useRef,引用之前的状态值
import { useRef, useState } from "react";
export default function App(){
const [count, setCount] = useState(0)
const prevCount = useRef()
function handleClick(){
prevCount.current = count
setCount(count + 1)
}
return (
<div style={{ padding: 10 }}>
<p>最新的count:{count}</p>
<p>上次的count:{prevCount.current}</p>
<button onClick={handleClick}>增大的count</button>
</div>
);
}
// react hooks,useRef,引用页面中的标签
import { useRef } from "react";
export default function App(){
const inputRef = useRef(null)
function handleClick(){
inputRef.current.focus()
}
return (
<div style={{ padding: 10 }}>
<input type="text" ref={inputRef} />
<button onClick={handleClick}>增大的count</button>
</div>
);
}
// react hooks,useRef,引用页面中的其他组件进行子组件功能访问
import { forwardRef, useImperativeHandle, useRef } from "react";
const Child = forwardRef(function (props, ref) {
useImperativeHandle(ref, () => ({
// 暴露父组件的方法
myFn: () => {
console.log("子组件的myFn方法");
},
}));
return <div>子组件</div>;
});
export default function App() {
const childRef = useRef();
function handleClick() {
childRef.current.myFn()
}
return (
<div>
<Child ref={childRef} />
<button onClick={handleClick}>按钮</button>
</div>
);
}