1
对于一个前端开发者来说,往往关注四个方面,路由,数据流,业务逻辑和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/


NsNe
1.7k 声望38 粉丝

善良,学习,拼搏。不忘初心,方得始终。