如何在 React 和 ReasonML 中使用 SVG?
How to Use SVG with React and ReasonML?
使用 create-react-app
和 JavaScript/TypeScript,我知道我能够 "import" 如下所述的 SVG。我如何使用 ReasonML 做到这一点?
import { ReactComponent as Logo } from './logo.svg';
function App() {
return (
<div>
{/* Logo is an actual React component */}
<Logo />
</div>
);
}
Create React App 使用 webpack 将 SVG 文件转换为 React 组件。如果您将 Reason 与 CRA 一起使用,那么您需要做的就是提供对生成组件的绑定。但是,如果导入语句完全按照特定方式编写,CRA 只会将 SVG 转换为组件,这不是 BuckleScript 输出导入语句的方式。 (There's a GitHub issue about it here.) 您必须使用原始 JavaScript 导入它,然后绑定到导入的值:
%bs.raw
{|import {ReactComponent as _Logo} from "./logo.svg"|};
module Logo = {
[@react.component] [@bs.val] external make: unit => React.element = "_Logo";
};
/* And we can use it like a regular component: */
[@react.component]
let make = () =>
<div>
<Logo />
</div>;
The imported SVG React Component accepts a title
prop along with other props that a svg
element accepts.
对于您想使用的任何其他道具,您必须将它们添加到您的 external
绑定中。
如果您不使用 CRA,那么您将需要配置您的捆绑器以执行相同的转换。我不熟悉 CRA 的内部结构,但是 this seems to be the relevant code from its webpack configuration.
我们可以使用 SVGR 来处理 webpack 加载,然后像往常一样导入模块。
const webpack = require('webpack');
module.exports = {
entry: './src/index.js',
module: {
rules: [
//...
{
test: /\.svg$/,
use: ['@svgr/webpack'],
},
],
},
//...
};
module Logo = {
@bs.module(`../../../../src/img/logo.svg`) @react.component
external make: {.} => React.element = "default"
}
...
<Logo /> // works
我是另一个不涉及 webpack 的解决方案的作者。
这是一个可以将您的 svg 文件直接转换为 .re 文件的工具:https://github.com/MoOx/react-from-svg
这可以为 React (dom) 或 react-native(-web) 创建文件(=> 使用 react-native-svg 生成的文件)。
欢迎尝试:)
例如你可以这样做(当从 npm 安装该工具时)
$ react-from-svg src/SVGs src/SVGs/components --with-native-for-reason --remove-fill
这会将 svg/SVGs
中的文件转换为 React 组件,并 src/SVGs/components
与 Reason 语法兼容 React Native。
最后一个选项删除所有 svg 填充道具,以便您可以将它们用作图标。
请注意,生成的组件接受 width
、height
和 fill
属性,因此您可以在使用时调整它们。
最后的好处:由于不涉及 webpack,因此只有在更新 SVG 文件时才能使用此转换并直接将此代码与 Node 运行时一起使用(Reason 中的 JSX 在转换为 JS 时会被删除,因此代码可以直接通过 Node 使用,无需任何转换 - 这对于微小的静态 sites/pages).
很方便
使用 create-react-app
和 JavaScript/TypeScript,我知道我能够 "import" 如下所述的 SVG。我如何使用 ReasonML 做到这一点?
import { ReactComponent as Logo } from './logo.svg';
function App() {
return (
<div>
{/* Logo is an actual React component */}
<Logo />
</div>
);
}
Create React App 使用 webpack 将 SVG 文件转换为 React 组件。如果您将 Reason 与 CRA 一起使用,那么您需要做的就是提供对生成组件的绑定。但是,如果导入语句完全按照特定方式编写,CRA 只会将 SVG 转换为组件,这不是 BuckleScript 输出导入语句的方式。 (There's a GitHub issue about it here.) 您必须使用原始 JavaScript 导入它,然后绑定到导入的值:
%bs.raw
{|import {ReactComponent as _Logo} from "./logo.svg"|};
module Logo = {
[@react.component] [@bs.val] external make: unit => React.element = "_Logo";
};
/* And we can use it like a regular component: */
[@react.component]
let make = () =>
<div>
<Logo />
</div>;
The imported SVG React Component accepts a
title
prop along with other props that asvg
element accepts.
对于您想使用的任何其他道具,您必须将它们添加到您的 external
绑定中。
如果您不使用 CRA,那么您将需要配置您的捆绑器以执行相同的转换。我不熟悉 CRA 的内部结构,但是 this seems to be the relevant code from its webpack configuration.
我们可以使用 SVGR 来处理 webpack 加载,然后像往常一样导入模块。
const webpack = require('webpack');
module.exports = {
entry: './src/index.js',
module: {
rules: [
//...
{
test: /\.svg$/,
use: ['@svgr/webpack'],
},
],
},
//...
};
module Logo = {
@bs.module(`../../../../src/img/logo.svg`) @react.component
external make: {.} => React.element = "default"
}
...
<Logo /> // works
我是另一个不涉及 webpack 的解决方案的作者。 这是一个可以将您的 svg 文件直接转换为 .re 文件的工具:https://github.com/MoOx/react-from-svg 这可以为 React (dom) 或 react-native(-web) 创建文件(=> 使用 react-native-svg 生成的文件)。 欢迎尝试:)
例如你可以这样做(当从 npm 安装该工具时)
$ react-from-svg src/SVGs src/SVGs/components --with-native-for-reason --remove-fill
这会将 svg/SVGs
中的文件转换为 React 组件,并 src/SVGs/components
与 Reason 语法兼容 React Native。
最后一个选项删除所有 svg 填充道具,以便您可以将它们用作图标。
请注意,生成的组件接受 width
、height
和 fill
属性,因此您可以在使用时调整它们。
最后的好处:由于不涉及 webpack,因此只有在更新 SVG 文件时才能使用此转换并直接将此代码与 Node 运行时一起使用(Reason 中的 JSX 在转换为 JS 时会被删除,因此代码可以直接通过 Node 使用,无需任何转换 - 这对于微小的静态 sites/pages).
很方便