前言
随着 React Hooks 成为 React 开发中的一部分,并且在 Hooks 上构建的函数式组件变得越来越普遍,Hooks API 也变得越来越重要。with-hooks 这个 npm 包便是一个实用的工具,帮助我们更好地使用 Hooks API,缩短 React Hooks 开发的周期和成本,使我们能够开发出更好和更高效的应用。
本文将介绍 npm 包 with-hooks 的使用方法,包括安装、API 名称及示例代码等内容。
with-hooks 概述
with-hooks 是一个可以通过 HOC 或者 render props 的方式来给组件注入 Hooks 的工具包。它让我们不用写自定义的 useContext 内容提供器和 useReducer 高阶组件,而是使用 with-hooks 工具包提供的 API,可以更快地编写具有逻辑的 React 组件。
安装
with-hooks 可以通过 npm 或者 yarm 安装。在你的 React 项目中,你可以使用以下命令来进行安装:
npm install with-hooks or yarn add with-hooks
简单使用示例
安装完成后,我们就可以开始使用 with-hooks 了。下面是一个只有 UI 的简单的 Login 组件:
-- -------------------- ---- ------- ------ ----- ---- -------- ------ ------- -------- ------------ - ------ - ----- ------ ---------------------- ---------------------- ------------- -- ---------------------------------- -- ------ ---------------------- ---------------------- ------------- -- ---------------------------------- -- ------- ------------------------------------ ------ -- -
接下来,我们需要使用 with-hooks 进行改编。我们需要导入 withHooks 方法,并创建一个使用 hooks 的 React 组件。对于 Login 组件,这个组件将保存一个 username 和一个 password 的状态,并允许用户使用它输入用户名和密码。我们还提供了一个 login 方法,该方法可以将 username 和 password 发送到服务器。
使用 withHooks 时,我们将不再需要使用状态(useState 和 useContext),而是只需要使用 withHooks 函数,它将会在组件中注入 useState 和 useContext 等 hooks。 我们只需要按照以下示例在 Login 组件的 JSX 中使用 withHooks。
-- -------------------- ---- ------- ------ ----- ---- -------- ------ - --------- - ---- ------------- -------- ------------ - -------- -------------- - --------------------------- ---------------- - ------ - ----- ------ ---------------------- ---------------------- ------------- -- ---------------------------------- -- ------ ---------------------- ---------------------- ------------- -- ---------------------------------- -- ------- ------------------------------------- ------ -- - ------ ------- ---------------- - --------- --- --------- --- ---
你可以看到,我们将 Login 组件传入 withHooks 函数来获得一个注入了 username
和 password
状态的新组件。
这个新组件可以像这样使用:
-- -------------------- ---- ------- ------ ----- ---- -------- ------ ---------- ---- ------------------ -------- ---------------- - -------- --------------------- --------- - ---------------------- --- -------- ----------- --- -------- -------------- - ------ - ----- --------- --------- ----------- ------------------- --- ------ -- -
正如你所见,withHooks 函数已经成功的给 LoginHooks 组件注入了 useState 和 useContext 这两个 Hooks。LoginHooks 组件也不用去调用 useState 和 useContext,因为它会自动从 withHooks 中接收这两个 Hooks,并将它们作为组件的 props。
这是一个简单的示例,让我们看一下 withHooks 可以做什么。
withHooks API
withHooks 函数有两个参数:一个 React 组件和一个可选的初始状态对象,它按照以下方式接收来自 React 组件的 props:
-- -------------------- ---- ------- ------ ------- ---------- ------------ - -------------- -------------- -------------- -------------- -- --- -------------- -------------- - --
其中,initialValueX
代表你的组件可能会使用的 hook,而 defaultValueX
代表你想要在初始化 hook 中使用的默认值。
如果你的组件中使用了的 Hooks 不在 withHooks 参数的初始状态中声明的话,withHooks 仍然会将它从 React 组件的 props 中传递给组件。
在上面的示例中,我们只使用了 useState,但 withHooks 也支持其他 Hooks,可以通过使用 withHooks-useContext
和 withHooks-useEffect
来使用这些 Hooks。
现在,我们将会学习更多使用示例。
高级示例
通过在 withHooks 参数的初始状态对象中定义 hooks,你就可以为许多状态组合建立一个全局的状态管理库了。这在更大规模的 React 应用中很有用,因为它使得我们可以管理所有组件并减少代码重复。
让我们通过一个具体的例子来进一步说明 withHooks 如何帮助我们进行更好的状态管理。
需求:
我们现在想要开发一个火车订票的功能。火车订票功能大致如下:
- 输入起始站点和目标站点。
- 点击“查询”按钮。
- 显示可用的列车列表。
- 选择一个列车并输入个人信息。
- 提交后需要保存用户信息,并跳转到支付页面。
步骤:
第一步:我们需要在 create-react-app 中创建一个名为 “TicketBooking” 的项目
# Commands to create a new React Application npx create-react-app TicketBooking cd TicketBooking npm start
第二步:我们创建一个 TicketBooking
和一个 TrainBooking
组件。 TicketBooking
组件将包含用户查询的表单以及列车信息,而 TrainBooking
组件将包含列车选择和用户信息输入表单。
-- -------------------- ---- ------- -- ----------------- ------ ----- ---- -------- ------ ------------ ---- ----------------- ------ ------- -------- -------------------- - ------ - ----- ----- ----- ------------------------------ ------- ---- ------ ----------- ------------------ --------------------------------- -- -------- --- -- ------- -- ------ ----------- ---------------- ------------------------------- -- -------- --- -- ------- ----------------------------- ------- ------ ------------- - - ------------- --------------------- -- - - - --------- ------ --- ------ ---------- -- ------ -- -
-- -------------------- ---- ------- -- ---------------- ------ ----- ---- -------- ------ ------- -------- ------------------- - ------ - ----- --------- ---------- ---- ------------------------- -- - --- --------------------- ----------------------------- ------------------------- ----------------------- ----- --- ----- ----- ----- ---------------------------- ------- ---- ----- ------ ----------- ---------------------- ------------------------------- -- -------- --- -- ------- ------ ------ ----------- ------------------- ---------------------------- -- -------- --- -- ------- ------------------ --------------- ------- ------ ------ -- -
现在我们需要为 TicketBooking
和 TrainBooking
组件添加状态,以便我们可以存储用户输入的信息,以及列车信息。
我们可以使用 with-hooks
来为 TicketBooking
和 TrainBooking
添加状态管理功能。请看下面对 TrainBooking
组件的修改:
-- -------------------- ---- ------- ------ ----- ---- -------- ------ - --------- - ---- ------------- -------- ------------------- - -------- ------------ - ------------------------------- --------------- ------------- - -------- --------------------- - --------------------------- - ------ - ----- --------- ---------- ---- ------------------------- -- - --- --------------------- ----------------------------- ------------------------- ----------------------- ------- ----------- -- -------------------------------------------------- ----- --- ----- ----- ----- ---------------------- ------- ---- ----- ------ ----------- ---------------------- ------------- -- ---------------------------------- -- -------- --- -- ------- ------ ------ ----------- ------------------- ------------- -- ------------------------------- -- -------- --- -- ------- ------------------ --------------- ------- ------ ------ -- - ------ ------- ----------------------- - ------- --- -------------- ----- --------- --- ------ --- ---
在上述修改中,我们先是通过 withHooks
添加了 trains
、selectedTrain
、fullname
和 email
状态。然后,我们在 JSX 中使用了这些状态。
我们在 TrainBooking
组件中定义了两个事件处理程序 handleBook
和 handleTrainChange
。handleBook
用于将用户信息和列车编号提交,而 handleTrainChange
用于将所选列车的 ID 存储在组件状态中。
现在我们需要为 TicketBooking
组件添加状态。我们同样可以使用 with-hooks
为 TicketBooking
添加状态。请看下面对 TicketBooking
组件的修改:
-- -------------------- ---- ------- ------ ----- ---- -------- ------ - --------- - ---- ------------- -------- -------------------- - ------ - ----- ----- ----- ------------------------------ ------- ---- ------ ----------- ------------------ ------------- -- ------------------------------ -- -------- --- -- ------- -- ------ ----------- ---------------- ------------- -- ---------------------------- -- -------- --- -- ------- ----------------------------- ------- ------ ------------- - - ------------- --------------------- -- - - - --------- ------ --- ------ ---------- -- ------ -- - ------ ------- ------------------------ - ------- ----- ----- --- --- --- ---
在上述修改中,我们添加 props.setFrom
,props.setTo
和 props.handleSearch
事件处理程序。这些处理程序将会返回响应的数据,以便我们可以触发查询操作。
现在我们已经完成了所有的状态管理代码,看起来还不错,但在 Route 状态中保存信息并不是很安全。因此,我们需要将此代码放置在一个全局状态管理库中。
因此,我们可以在一个新的 !redux store 中创建一个状态管理库,它会为每个页面或组件提供相同的状态。
-- -------------------- ---- ------- -- -------- ------ - ----------- - ---- -------- ----- ------------ - - ------- ----- ----- --- --- --- ---------------- ----- --------- --- ------ --- -- -------- ----------------- - ------------- ------- - ------ ------ - ----- ----- - ------------------------- ------ ------- ------
我们需要更新 TrainBooking
和 TicketBooking
组件来使用 redux store 中的状态。TrainBooking
组件与之前的状态管理器相同,但它会从 store 中获取它的 props。然后,我们将其与mapStateToProps
方法一起发送到 connect()
函数中。请注意,此时我们已经从全局状态管理库中获取所有状态。因此,我们不需要再在此处定义任何状态。
-- -------------------- ---- ------- ------ ----- ---- -------- ------ - ------- - ---- -------------- ------ - ---------------- - ---- --------------------- -------- ------------------- - -------- ------------ - --------------------------------- --------------- ------------- - -------- --------------------- - --------------------------- - ------ - ----- --------- ---------- ---- ------------------------- -- - --- --------------------- ----------------------------- ------------------------- ----------------------- ------- ----------- -- -------------------------------------------------- ----- --- ----- ----- ----- ---------------------- ------- ---- ----- ------ ----------- ---------------------- ------------- -- ---------------------------------- -- -------- --- -- ------- ------ ------ ----------- ------------------- ------------- -- ------------------------------- -- -------- --- -- ------- ------------------ --------------- ------- ------ ------ -- - -------- ---------------------- - ----- - ------- ---------------- --------- ----- - - ------ ------ - ------- ---------------- --------- ------ -- - ----- ------------------ - - ----------------- -- ------ ------- ------------------------ ----------------------------------
最后,我们需要在 TicketBooking
中更新 redux store 来接收传递给它的 props。
-- -------------------- ---- ------- ------ ----- ---- -------- ------ - ------- - ---- -------------- ------ - -------- ------ ----------- - ---- ------------------ -------- -------------------- - ------ - ----- ----- ----- ------------------------------ ------- ---- ------ ----------- ------------------ ------------- -- ------------------------------ -- -------- --- -- ------- -- ------ ----------- ---------------- ------------- -- ---------------------------- -- -------- --- -- ------- ----------------------------- ------- ------ ------------- - - ------------- --------------------- -- - - - --------- ------ --- ------ ---------- -- ------ -- - -------- ---------------------- - ----- - ------- ----- -- - - ------ ------ - ------- ----- --- -- - ----- ------------------ - - -------- ------ ------------- ------------ -- ------ ------- ------------------------ -----------------------------------
最后,我们需要在 index.js
中将 store 组件包裹在<Provider />
中,这样我们才能在整个应用中使用 “redux store”。
-- -------------------- ---- ------- ------ ----- ---- -------- ------ -------- ---- ------------ ------ - -------- - ---- -------------- ------ ----- ---- ---------- ------ ------------- ---- ------------------ ---------------- --------- -------------- -------------- -- ------------ ------------------------------- --
结论
我们已经介绍了 with-hooks 的使用方法,可以看到它是一种快捷使用 Hooks API 的方式。在复杂的 React 应用中,with-hooks 可以更快、更好地管理状态,帮助我们快速进行 React Hooks 的开发。在使用 with-hooks 时,通过框架将 React 的核心功能封装在 single responsiblity 风格里,可使我们更好地维护更高度可重复使用的代码。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6005a04d81e8991b448ed4f9