react 自定义 hooks
简介
一句话:使用自定义hooks可以将某些组件逻辑提取到可重用的函数中。
自定义hooks是一个从use开始的调用其他hooks的Javascript函数。
下面以一个案例: 新闻发布操作,来简单说一下react 自定义 hooks。
不使用自定义hooks时
未发布新闻 – UnPublished.js
// UnPublished.jsimport React, { useEffect, useState } from "react";
import { fetchGetUnPublishedNewsList } from "../../../utils/api";
import NewsPublish from "./components/NewsPublish";import { reactLocalStorage } from "reactjs-localstorage";export default function UnPublished() {// 获取用户权限列表const { roleId, region, username } = reactLocalStorage.getObject("token");const [dataSource, setdataSource] = useState([]);useEffect(() => {const fetchData = async () => {let params = {author: username,publishState: 1, // publishStateList = ['未发布','待发布','已发布','已下线']};const newsListData = await fetchGetUnPublishedNewsList(params); setdataSource(newsListData);};fetchData();}, []);return (<div><NewsPublish dataSource={dataSource}></NewsPublish></div>);
}
发布新闻 – Published.js
// Published.jsimport React, { useEffect, useState } from "react";
import { fetchGetUnPublishedNewsList } from "../../../utils/api";
import NewsPublish from "./components/NewsPublish";import { reactLocalStorage } from "reactjs-localstorage";export default function UnPublished() {// 获取用户权限列表const { roleId, region, username } = reactLocalStorage.getObject("token");const [dataSource, setdataSource] = useState([]);useEffect(() => {const fetchData = async () => {let params = {author: username,publishState: 3, // publishStateList = ['未发布','待发布','已发布','已下线']};const newsListData = await fetchGetUnPublishedNewsList(params); setdataSource(newsListData);};fetchData();}, []);return (<div><NewsPublish dataSource={dataSource}></NewsPublish></div>);
}
很明显,以上两个文件呈现效果不同,但使用的 逻辑代码大部分相同 时,这些逻辑代码我们就可以使用hooks进行逻辑复用。
使用自定义hooks
我们抽离以上两个文件里可以复用的逻辑代码,抽离相同逻辑代码部分,自定义hooks (即:把fetch请求数据部分,单独抽离出来),新建一个usePublish的文件。
./components/usePublish
// ./components/usePublishimport { useEffect, useState } from "react";
import { fetchGetUnPublishedNewsList } from "../../../../utils/api";
import { reactLocalStorage } from "reactjs-localstorage";function usePublish(type) { // 注意这里// 获取用户权限列表const { username } = reactLocalStorage.getObject("token");const [dataSource, setdataSource] = useState([]);useEffect(() => {const fetchData = async () => {let params = {author: username,publishState: type, // publishStateList = ['未发布','待发布','已发布','已下线']};const newsListData = await fetchGetUnPublishedNewsList(params);setdataSource(newsListData);};fetchData();}, []);return { dataSource };
}export default usePublish;
未发布新闻 – UnPublished.js
改进
import NewsPublish from "./components/NewsPublish"; import usePublish from "./components/usePublish"; // 引入自定义hooksexport default function UnPublished() { const { dataSource } = usePublish(1); // 使用自定义hooksreturn (<div> <NewsPublish dataSource={dataSource}></NewsPublish></div>);
}
发布新闻 – Published.js
改进
import NewsPublish from "./components/NewsPublish";import usePublish from "./components/usePublish"; // 引入自定义hooksexport default function Published() {const { dataSource } = usePublish(2); // 使用自定义hooksreturn (<div><NewsPublishdataSource={dataSource}></NewsPublish></div>);
}
自定义hooks实质
- 自定义 Hooks 是一个函数,约定函数名称必须以 use 开头,React 就是通过函数名称是否以 use 开头来判断是不是 Hooks
- Hooks 只能在函数组件中或其他自定义 Hooks 中使用,否则,会报错!
- 自定义 Hooks 用来提取组件的状态逻辑,根据不同功能可以有不同的参数和返回值(就像使用普通函数一样)
总结
这个案例简单说明了如何使用react自定义hooks
。
在自定义hooks时,我们需要考虑几个问题:
- 什么时候使用自定义hooks?
- 使用自定hooks时应该传入什么参数,又返回出什么值?
- 使用自定义hooks,我的代码逻辑有没有变简洁?
什么时候使用自定义hooks?
- 发现某处业务逻辑重复使用时,可将业务逻辑抽离开
- 组件比较复杂时,可通过自定义hooks拆分组件逻辑,简化代码
使用自定hooks时应该传入什么参数,又返回出什么值?
传参和返回值是比较灵活的,需要注意的是,不仅能传常规的数据类型,还能传递函数对象
为什么时候自定义hooks,我的代码好像没有变简洁?
要理解UI组件和容器组件这两个概念。
恰当的抽离业务逻辑部分,保留组件的UI部分。
组件复杂时拆分可能也有一定的难度,过度设计会导致组件更难维护,因此要把控好度 。
参考文档
- https://blog.csdn.net/DDAD9527/article/details/121341862