发布于 2026-01-06 9 阅读
0

如何在 Reason 中使用 useContext Hook 创建音乐播放器(第一部分)我们要构建什么?

如何在 Reason 中使用 useContext Hook 创建音乐播放器(第一部分)

我们正在建造什么?

更新

ReasonML + BuckleScript 现已合并为 Rescript

由于这些工具的生态系统发生了变化,本文内容不再准确。


我们正在建造什么?

本教程将向您展示如何使用ReasonReacthooks构建一个音乐播放器useContext

您将学习如何启动一个 ReasonReact 项目,如何构建一个简单的应用程序,以及如何将 hooks 与 ReasonReact 结合使用。

☞ 查看演示

为什么选择 ReasonML 和 ReasonReact?

ReasonReact提供了一种类型安全的方式来构建 React 应用。它利用了成熟的 OCaml 语言,该语言拥有卓越的类型系统。此外,它还提供了速度极快的编译器和出色的面向 JavaScript 的工具。

免责声明:我本人也是 ReasonReact 的初学者,因此无法保证本教程完全遵循最佳实践。

本系列博客文章改编自 James King 撰写的优秀文章《如何在 React 中使用 useContext Hook》 。

本教程假定读者已具备 React 的基本知识。ReasonReact 的底层正是 React。

你可以在GitHub上找到所有代码

这是什么useContext

来自React 文档

Context 旨在共享 React 组件树中可视为“全局”的数据,例如当前已验证用户、主题或首选语言。

我们将构建一个自定义MusicPlayer组件和一个useMusicPlayer钩子,使我们的应用程序能够访问一个简单的 mp3 HTML 音频播放器

项目启动

ReasonML 是 OCaml 的一种语法和工具链,我们需要安装一些 npm 包才能使用它。您需要Node.jsnpm(或 yarn)。

安装

安装Bucklescript 和 Reason

npm install -g bs-platform --unsafe-perm
Enter fullscreen mode Exit fullscreen mode

(我使用pnpm安装本地软件包,所以你会在仓库pnpm-lock.yml中找到一个文件。)

我们需要 BuckleScript 将 ReasonML 编译成 JavaScript。

关于编辑器支持,请查看Reason 文档

关于 Vim,您可以查看我关于使用 Vim 进行 ReasonML 开发的博客文章。

创建 ReasonReact 项目

在您的终端中:

bsb -init reason-music-player -theme react-hooks
cd reason-music-player && npm install
Enter fullscreen mode Exit fullscreen mode

这些命令会创建一个样板项目,我们需要根据自己的需要进行配置。

请注意:样板代码已更改。我会帮助您使用webpack

设置项目。但有了新的配置,这不再是绝对必要的。 如果您不想使用 webpack,可以使用新的默认样板代码,具体说明请参见[此处]

README

首先,bsconfig.json该文件告诉BuckleScript如何处理编译成 JavaScript 的过程:

{
  "name": "reason-music-player",
  "reason": {
    "react-jsx": 3
  },
  "sources": {
    "dir": "src",
    "subdirs": true
  },
  "package-specs": [
    {
      "module": "es6", // *new*: use ES6 imports
      "in-source": true
    }
  ],
  "suffix": ".bs.js",
  "namespace": true,
  "bs-dependencies": ["reason-react"],
  "refmt": 3
}
Enter fullscreen mode Exit fullscreen mode

我们的package.json界面对于 JavaScript 开发者来说应该很熟悉。我们将同时安装webpack 和 Bucklescript,以便它们能够一起运行:

npm i --save-dev concurrently
Enter fullscreen mode Exit fullscreen mode

调整脚本部分package.json

scripts": {
    "start": "concurrently -k \"npm run start:bsb\" \"npm run start:webpack\"",
    "start:bsb": "bsb -clean-world -make-world -w",
    "start:webpack": "webpack-dev-server --port 3000",
    "build": "npm run build:webpack",
    "build:webpack": "NODE_ENV=production webpack",
    "format": "refmt src/*.re"
  },
Enter fullscreen mode Exit fullscreen mode

我们还需要一个webpack的配置文件:

const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const outputDir = path.join(__dirname, 'build/')

const isProd = process.env.NODE_ENV === 'production'

module.exports = {
  entry: './src/Index.bs.js',
  mode: isProd ? 'production' : 'development',
  output: {
    path: outputDir,
    filename: 'Index.js',
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html',
      favicon: './src/favicon.ico',
      inject: false,
    }),
  ],
  devServer: {
    compress: true,
    contentBase: outputDir,
    port: process.env.PORT || 8000,
    historyApiFallback: true,
  },
}
Enter fullscreen mode Exit fullscreen mode

现在我们可以在终端运行该项目,并在以下位置查看结果https://localhost:3000

npm run start
Enter fullscreen mode Exit fullscreen mode

示例项目包含示例组件,我们将删除这些组件。只保留src/Index.re.

打开index.html文件并替换内容:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link
      rel="stylesheet"
      href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.5/css/bulma.min.css"
    />
    <link
      rel="stylesheet"
      href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.10.2/css/fontawesome.min.css"
    />
    <link
      rel="stylesheet"
      href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.10.2/css/solid.min.css"
    />
    <title>Reason Music Player</title>
  </head>
  <body>
    <div id="root"></div>
    <script src="Index.js"></script>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

现在我们也可以使用Bulma CSSFont Awesome 图标了

我们还会修改src/Index.re

ReactDOMRe.renderToElementWithId(<App />, "root");
Enter fullscreen mode Exit fullscreen mode

我们的索引组件现在会将id 为“root”App的组件渲染到 HTML 中div。我们会看到一个错误,因为该App组件尚不存在。

让我们一起创造它:

src/App.re


[@react.component]
let make = () => <div />
Enter fullscreen mode Exit fullscreen mode

这个语法看起来有点奇怪。每个 ReasonReact 组件都有一个make函数,用于创建一个 React 元素。ReasonReact底层

使用了函数式组件和React Hooks 。更多详情

请查看ReasonReact 文档。

我们将创建一个辅助函数来渲染 JSX 中的字符串:

src/ReactUtils.re

external s: string => React.element = "%identity";
Enter fullscreen mode Exit fullscreen mode

更多信息请查看 Florian Hammerschmidt 在 dev.to 上的帖子。)

现在,让我们更新一下App组件:

open ReactUtils; // (A)

[@react.component]
let make = () =>
  <div className="section is-fullheignt">
    <div className="container">
      <div className="column is-6 is-offset-4">
        <h1 className="is-size-2 has-text-centered">
          {s("Reason Music Player")}    // (A)
        </h1>
        <br />
      </div>
    </div>
  </div>;

Enter fullscreen mode Exit fullscreen mode

我们导入了实用模块,现在可以渲染字符串了(参见A)。Reason 是类型安全的,所以你需要告诉程序你想在 JSX 中传递一个字符串。`s`是

BulmaclassName的样式设置方式。

概要

我们安装了 Reason 和 BuckleScript,并为我们的项目搭建了最基本的配置。

ReasonReact 和 BuckleScript 为 JavaScript 开发者提供了熟悉的工具体验。但我们已经发现 ReasonML 和 JavaScript 之间存在一些差异(例如语法、显式渲染字符串)。

延伸阅读

文章来源:https://dev.to/sophiabrandt/how-to-create-a-music-player-in-reason-with-the-usecontext-hook-part-1-59dj