react:React Hook函数
使用规则
只能在组件中或者其他自定义的Hook函数中调用
只能在组件的顶层调用,不能嵌套在if
、for
、 其他函数中
基础Hook 函数
useState
useState
是一个hook
函数,它允许我们向组件中添加一个状态变量,从而控制影响组件的渲染结果
示例1
function App() {// 创建一个状态变量// count: 状态变量,setCount: 更新状态变量的函数const [count, setCount] = useState(0)return (<div><p>当前数值是:{count}</p><button onClick={() => setCount(count + 1)}>加一</button></div>)
}
示例2
function App() {const [userName, setUserName] = useState("111");return (<div><inputtype="text"value={userName}placeholder="请输入"onChange={(e) => setUserName(e.target.value)}/><div>当前输入值是:{userName}</div></div>);
}
注意:
- 在
react
中,状态被认为是只读的,直接修改状态不能引发视图的更新 - 对于对象类型的状态变量,应该始终传给
set
方法一个全新的对象来进行修改
function App() {const [form, setForm] = useState({age: 0})return (<div><p>当前年龄是:{form.age}</p><button onClick={() => setForm({...form,age: form.age + 1})}>加一</button></div>)
}
useRef
获取、操作DOM
function App() {// 使用 useRef生成ref对象,并绑定到dom上const inputRef = useRef(null);// 获取domconst getDom = () => {console.log(inputRef.current);};return (<div><input type="text" ref={inputRef} placeholder="请输入" /><button onClick={getDom}>获取dom</button></div>);
}
useEffect
useEffect
是一个React Hook
函数,用于在React
组件中创建不是由事件引起而是由渲染本身引起的操作,比如发送AJAX
请求、更改DOM
等
function App() {const [content, setContent] = useState("");const [note, setNote] = useState("");useEffect(() => {// 获取每日英语function getEnglish() {fetch("https://api.oioweb.cn/api/common/OneDayEnglish").then((res) => res.json()).then((data) => {console.log(data);setContent(data.result.content);setNote(data.result.note);});}getEnglish();}, []);return (<div><div>英文:{content}</div><div>翻译:{note}</div></div>);
}
不同依赖项说明
- 没有依赖项,组件初始渲染+组件更新时执行
- 空数组依赖,只在初始渲染时执行一次
- 添加特定依赖项,组件初始渲染+特性依赖项变化时执行
没有依赖项
function App() {const [content, setContent] = useState(0);useEffect(() => {console.log("副作用执行了");});return (<div><button onClick={() => setContent(content + 1)}>{content}</button></div>);
}
空数组依赖
function App() {const [content, setContent] = useState(0);useEffect(() => {console.log("副作用执行了");}, []);return (<div><button onClick={() => setContent(content + 1)}>{content}</button></div>);
}
特性依赖变化
function App() {const [content, setContent] = useState(0);useEffect(() => {console.log("副作用执行了");}, [content]);return (<div><button onClick={() => setContent(content + 1)}>{content}</button></div>);
}
清除副作用
在useEffect
中编写的由渲染本身引起的对接组件外部的操作, 社区也叫做副作用操作,比如在useEffect
中开启了一个定时器,我们想在组件卸载时把这个定时器再清理掉,这个过程就是清除副作用。
useEffect(() => {console.log("副作用执行了");return () => {console.log("清除副作用");};
}, []);
清除副作用的函数最常见的执行时机是在组件卸载时自动执行。
function App() {const [show, setShow] = useState(true);return (<div>父组件<button onClick={() => setShow(false)}>卸载Son组件</button>{show && <Son />}</div>);
}
function Son() {const [currentDate, setCurrentDate] = useState("");useEffect(() => {const timer = setInterval(() => {const newDate = new Date().toLocaleTimeString();setCurrentDate(newDate);console.log("当前时间:", newDate);}, 1000);return () => {// 不清除副作用,即使组件不适用了,定时器还会执行clearInterval(timer);};}, []);return (<div><div>子组件</div><div>当前时间是:{currentDate}</div></div>);
}
自定义Hook
自定义Hook是以use
打头的函数,通过自定义Hook函数可以用来实现逻辑的封装和复用
function App() {const [state, toggle] = useToggle()return (<div>{ state && <div>这是一个div</div> }<button onClick={toggle}>切换</button></div>)
}function useToggle(){// 可复用的逻辑代码const [state, setState] = useState(true)const toggle = () => {setState(!state)}// 那些状态和方法需要在其他组件中使用,则返回return [state, toggle]
}
通用思路
- 声明一个以
use
大头的函数 - 在函数体内封装可以复用的逻辑
- 将组件中用的的状态或者回调函数return出去(对象或者数组形式)
- 在那个组件中用到这个逻辑,就执行这个函数,结构出来状态和回调进行使用
function App() {const [content, note] = useOneDayEnglish();return (<div><div>英文:{content}</div><div>翻译:{note}</div></div>);
}function useOneDayEnglish() {const [content, setContent] = useState("");const [note, setNote] = useState("");useEffect(() => {// 获取每日英语function getEnglish() {fetch("https://api.oioweb.cn/api/common/OneDayEnglish").then((res) => res.json()).then((data) => {console.log(data);setContent(data.result.content);setNote(data.result.note);});}getEnglish();}, []);return [content, note];
}