对于一个前端开发者来说,往往关注四个方面,路由,数据流,业务逻辑和ui页面,如下从一个自定义hook开始,后续讲解了各个方面都可以去使用hook去更简单实现业务场景。代码可读性,维护性都可大大增强。
对于开发者来说,函数是对某一个功能的封装,那么 hook
就是对相同逻辑功能的封装。
当你觉得重复在做一件事情的时候,那么你会把它封装成一个函数。同理,当你觉得在写重复的逻辑时,那么它就可以是一个 hook
。
如何自定义 hook
自定义 Hook 是一个函数,其名称以 “use
” 开头,函数内部可以调用其他的 Hook
例如我们来为 modal
的显示隐藏做一个 hooks
const useShowModal = (visible, data) => {
const [modalVisible, setModalVisible] = useState(visible);
const [modalData, setModalData] = useState(data);
const updateModal = (v, d) => {
setModalVisible(v);
setModalData(d);
};
return {
visible: modalVisible,
data: modalData,
updateModal,
};
};
export default useShowModal;
可以通过此 hook
做如下的添加,删除和取消 modal
操作
const {visible, data, updateModal} = useShowModal(false);
const onAdd = () => {
updateImportModal(true);
}
const onEdit = (item) => {
updateModal(true, item);
}
const onCancel = () => {
updateModal(false);
}
在项目中使用 hook
react-router
- useHistory
获取
history
实例,操作路由
import { useHistory } from "react-router-dom";
function HomeButton() {
let history = useHistory();
function handleClick() {
history.push("/home");
}
return (
<button type="button" onClick={handleClick}>
Go home
</button>
);
}
- useLocation
获取路由 location
对象
import React from "react";
import ReactDOM from "react-dom";
import {
BrowserRouter as Router,
Switch,
useLocation
} from "react-router-dom";
function usePageViews() {
let location = useLocation();
React.useEffect(() => {
ga.send(["pageview", location.pathname]);
}, [location]);
}
function App() {
usePageViews();
return <Switch>...</Switch>;
}
ReactDOM.render(
<Router>
<App />
</Router>,
node
);
- useParams
获取 url
路径匹配的参数
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router, Switch, Route, useParams } from 'react-router-dom';
function BlogPost() {
let { slug } = useParams();
return <div>Now showing post {slug}</div>;
}
ReactDOM.render(
<Router>
<Switch>
<Route exact path="/">
<HomePage />
</Route>
<Route path="/blog/:slug">
<BlogPost />
</Route>
</Switch>
</Router>,
node,
);
- useRouteMatch
获取到 match
对象,对之前的写法,拍平
import { Route } from "react-router-dom";
// 以前这样做
function BlogPost() {
return (
<Route
path="/blog/:slug"
render={({ match }) => {
// Do whatever you want with the match...
return <div />;
}}
/>
);
}
// 现在可以这样做
import { useRouteMatch } from "react-router-dom";
function BlogPost() {
let match = useRouteMatch("/blog/:slug");
// Do whatever you want with the match...
return <div />;
}
以上为 react-router
内置的hooks,那对于我们通常使用来说,还可能获取search参数(?后的参数),我们也可以封装自己的hook,可以是如下这样
function useQuery() {
return new URLSearchParams(useLocation().search);
}
// 使用
let query = useQuery();
const id = query.get('id');
或者,也可以这样
function useSearchParams(id) {
const query = new URLSearchParams(useLocation().search);
return query.get(id);
}
// 使用
useSearchParams('id');
redux hook
redux 目前也支持了 hook,相关内容参见 https://react-redux.js.org/ap...
react-use
一个强大的工具库,http://streamich.github.io/react-use 读者可在其中搜索相关的工具 hook
umijs/hooks
一个完备的库,实现了各种列表功能
https://hooks.umijs.org/
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。