将 Blazor Web Assembly 集成到 ReactJS 中

问题描述 投票:0回答:1

任务: 有一个用C#编写的类库。有必要让一种方法可用于从 ReactJS 调用。我决定使用 Blazor WebAssembly 来完成此任务。我的目的是

dotnet publish
一个用 BWASM 编写的项目。之后,需要通过ReactJS连接已发布的文件,以便进一步从这些已发布的文件中调用函数。

需要调用 MdProcessor.ParseAndRender 函数,向其传递一个字符串作为输入,并从中获取字符串结果

解决方案: BWASM 的 Program.cs:

using MarkdownProcessorWasm;
using MdPWASM;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Microsoft.JSInterop;
using System;
using System.Threading.Tasks;
using MarkdownProcessor;
using MarkdownProcessor.Classes;
using MarkdownProcessor.Interfaces;
using MarkdownProcessor.Structs.Tags;

var builder = WebAssemblyHostBuilder.CreateDefault(args);

var host = builder.Build();

var jsRuntime = host.Services.GetRequiredService<IJSRuntime>();
await jsRuntime.InvokeVoidAsync("console.log", "Hello World from Blazor WebAssembly!");

var jsInterop = new MarkdownProcessorInterop();

await jsRuntime.InvokeVoidAsync("blazorInterop.registerProcessor", DotNetObjectReference.Create(jsInterop));

await host.RunAsync();

public class MarkdownProcessorInterop
{
    private MdProcessor _markdownProcessor;

    public MarkdownProcessorInterop()
    {
        var ital = new ItalicsTag();
        var bold = new BoldTag();
        var link = new Link();
        var header = new HeaderTag();
        var main = new MainTag();
        var list = new List<ITag> { bold, ital, link, header, main };

        _markdownProcessor = new MdProcessor(new StringParser(list), new ConsoleMdRenderer());
    }
        
    [JSInvokable]
    public string ParseMarkdown(string markdownText)
    {
        return _markdownProcessor.ParseAndRender(markdownText);
    }
}

WASM 的index.html:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>MdPWASM</title>
    <base href="/" />
    <link rel="stylesheet" href="css/app.css" />
    <!-- If you add any scoped CSS files, uncomment the following to load them
    <link href="MdPWASM.styles.css" rel="stylesheet" /> -->
</head>

<body>
    <script>
        window.blazorInterop = {
            registerProcessor: function (processor) {
                window.processor = processor;
            },
            parseMarkdown: async function (markdownText) {
                if (!window.processor) {
                    throw new Error("WASM module is not ready yet.");
                }
                return await window.processor.invokeMethodAsync("ParseMarkdown", markdownText);
            }
        };
    </script>
    <script src="_framework/blazor.webassembly.js"></script>
    <script src="Interop.js"></script>
</body>

</html>

我们的想法是为 window 添加 parseMarkdown 属性,以便稍后通过 DOM 我们可以在 JS 中调用所需的函数。

这是 React 中客户端的代码:

useEffect(() => {
        const loadBlazor = async () => {
            try {
                await import('http://localhost:8080/_framework/blazor.webassembly.js');

                await window.Blazor.start({
                    loadBootResource: (type, name, defaultUri, integrity) => {
                        return `http://localhost:8080/_framework/${name}`;
                    }
                }).then(() => {
                    console.log('Blazor WebAssembly is initialized');
                }).catch(error => {
                    console.error('Blazor WebAssembly initialization error:', error);
                });
            } catch (error) {
                console.error('Error while fetching Blazor WebAssembly:', error);
            }
        };

        loadBlazor();
    }, []);

    const processMarkdown = async () => {
        try {
            if (window.processor) {
                const parsedHtml = await window.blazorInterop.parseMarkdown(markdownText);
                setHtmlOutput(parsedHtml);
            } else {
                console.error('Blazor WebAssembly is not loaded');
            }
        } catch (error) {
            console.error('Error while parsing Markdown:', error);
        }
    };

通过 localhost:8080,我们收到将 C# 编写的代码集成到 JS 所需的 dotnet 发布的文件。 WebAssembly加载成功,即使用Blazor编写的console.log调用函数也能成功,但下一行出现错误: ManagedError:发生一个或多个错误。 (找不到“blazorInterop.registerProcessor”(“blazorInterop”未定义)。 错误:找不到“blazorInterop.registerProcessor”(“blazorInterop”未定义)。

问题: 问题是当我们尝试打电话时

await jsRuntime.InvokeVoidAsync("blazorInterop.registerProcessor", DotNetObjectReference.Create(jsInterop));
在 BWASM 中,blazorInterop 属性尚未在 window 上创建。我试图延迟访问 blazorInterop 的时刻,直到它被声明,但我陷入了无限循环。看起来它永远不会被宣布。如何解决这个问题呢?如何在 window 上声明 blazorInterop 作为其属性?有什么方法可以将我的 MdProcessor 类库转换为 wasm 但保留 ReactJS 作为主要且唯一的前端框架?我将非常感谢任何帮助,最好是建设性的帮助

c# reactjs blazor-webassembly
1个回答
0
投票

我通过添加解决了问题

<script>
      window.blazorInterop = {
        registerProcessor: function (processor) {
          window.processor = processor;
        },
        parseMarkdown: async function (markdownText) {
          if (!window.processor) {
            throw new Error("WASM module is not ready yet.");
          }
          return await window.processor.invokeMethodAsync("ParseMarkdown", markdownText);
        }
      };
    </script>

React 客户端代码中的index.html 所以当 Blazor 尝试使用注册处理器时

await jsRuntime.InvokeVoidAsync("blazorInterop.registerProcessor", DotNetObjectReference.Create(jsInterop));
处理器将已经在 DOM 中。

© www.soinside.com 2019 - 2024. All rights reserved.