阅读视图

发现新文章,点击刷新页面。
🔲 ☆

Husky 入门教程

Husky

Husky 是一个 NPM 包,用更好的使用 Git 钩子来管理项目。通常它被用于项目的代码提交前的各类规范的检查。

安装和配置

  1. 安装 Husky

    1
    npm install husky --save-dev
  2. 启用 Husky

    1
    npx husky install
  3. 在 package.json 中添加 prepare 钩子,用于在 npm install 之后自动启用 Husky

    1
    npm set-script prepare "husky install"

    package.json 文件将会添加一个 prepare script:

    1
    2
    3
    4
    5
    {
    "scripts": {
    "prepare": "husky install"
    }
    }

创建钩子

1
npx husky add .husky/pre-commit "npm run lint"

配合 lint-staged 使用

lint-staged 是一个在提交代码前,只检查提交的文件的工具。它可以配合 Husky 使用,只检查提交的文件,而不是整个项目。

  1. 在项目中安装 lint-stagedeslint(或其他你需要的规范检查工具)

    1
    npm install lint-staged eslint --save-dev
  2. package.json 中添加 lint-staged 配置

    1
    2
    3
    4
    5
    {
    "lint-staged": {
    "*.{js,jsx,ts,tsx}": "eslint --fix"
    }
    }
  3. 创建使用 lint-staged 的钩子

    1
    npx husky add .husky/pre-commit "npx lint-staged"

配合 commitlint 使用

commitlint 是一个用于检查提交信息是否符合规范的工具。它可以配合 Husky 使用,检查提交信息是否符合规范。

  1. 在项目中安装 @commitlint/cli@commitlint/config-conventional

    1
    npm install @commitlint/cli @commitlint/config-conventional --save-dev
  2. 在项目根目录创建 commitlint.config.js 文件

    1
    module.exports = { extends: ["@commitlint/config-conventional"] };
  3. 创建使用 commitlint 的钩子

    1
    npx husky add .husky/commit-msg "npx --no-install commitlint --edit $1"

结语

Husky 是一个非常好用的工具,可以帮助我们更好的管理项目的代码提交规范。用来解决因个人编码风格差异引发的潜在冲突,提升团队协作效率。

🔲 ⭐

怎么使用 React Context API ?

React context 是 React 提供的基本工具,用于在组件间共享状态。

本文介绍 React context 的基本用法。

React Context API

什么是 React Context?

React context 允许我们不对组件树的每层组件手动添加 props 来传递数据的情况下,在组件间共享数据。它能让我们更容易的跨组件共享状态。

什么时候使用 React Context?

当某些状态可能在任何组件中都会被使用时,React context 是非常有用的。

比如:

  • UI 主题状态(亮暗模式、用户定制的 UI 风格等)
  • 当前会话的用户数据(用户名、头像等)
  • 当前语言或区域

React context 会让项目里的任何组件都能轻松访问到这些状态。

React context 解决了什么问题?

React context 帮我们解决了 props drilling 问题。

Props drilling 是指状态以 props 的形式从 React 组件树中一直往下传递, 但中间层组件并不需要这些 props, 只是做一个向下转发,这种情况就叫做 props drilling。

下面是一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
export default function App() {
const [user, setUser] = useState({ name: 'Eson', age: 18 });

return (
<Header user={user}>
)
}

const Header = ({ user }) => {
return (
<>
<Menu user={user}>
</>
)
}

你可以看到,Header 组件中的 user 状态是通过 props drilling 来获取的。App 的直接子组件 Header 并不需要 user 状态,它只是做一个向下转发。

怎么使用 React context?

  1. 使用 React context API React.createContext 方法创建 context

    1
    2
    3
    const UserContext = React.createContext({ name: "Eson", age: 18 }); // 第一个参数是默认值

    export default UserContext;
  2. 使用 React context 的 Provider 组件包裹你的组件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    import React, { useState } from "react";
    import UserContext from "userContext.js";

    const App = () => {
    const [user, setUser] = useState({ name: "Eson", age: 18 });

    return (
    <UserContext.Provider value={user}>
    <Header />
    </UserContext.Provider>
    );
    };
  3. 使用 React context 的 Consumer 组件获取 context 状态,提供给使用状态的组件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    import React from "react";
    import UserContext from "userContext.js";

    const Header = () => {
    return <Menu />;
    };

    const Menu = () => {
    return (
    <UserContext.Consumer>
    {(user) => (
    <div>
    {user.name}
    <button>退出</button>
    </div>
    )}
    </UserContext.Consumer>
    );
    };

上面的示例代码中,被 UserContext.Provider 组件包裹的组件树才可以通过 UserContext.Consumer 组件来获取用户的状态。

Context hook

随着 React 带来了 Hooks,我们可以使用 useContext 来获取 context 状态。

`useContext`` 接收一个 context 对象,返回一个 context 的值。它使我们的组件更加简洁,并允许我们创建自己的自定义钩子。

1
2
3
4
5
6
7
8
9
10
11
12
13
import React, { useContext } from "react";
import UserContext from "userContext.js";

const Menu = () => {
const user = useContext(UserContext);

return (
<div>
{user.name}
<button>退出</button>
</div>
);
};

使用 React context 的注意事项

解决 props drilling 的问题,React context 可以解决,但是它不是一个好的选择。第一是因为这会让组件的复用性变差,第二是 context 状态如果是一个对象,更新的时候会导致所有使用这个 context 的组件重新渲染,即使仅使用了未更新的属性值。

我们也可以更好组合我们的组件来解决这个问题,比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import React from "react";

const App = () => {
const [user, setUser] = useState({ name: "Eson", age: 18 });

return (
<Header>
<Menu user={user} />
</Header>
);
};

const Header = ({ children }) => {
return <header>{children}</header>;
};

const Menu = ({ user }) => {
return (
<div>
{user.name}
<button>退出</button>
</div>
);
};
❌