保存时钩子调用无效,使用鼠标滑块时未进行编辑

时间:2021-12-26 作者:user8463989

我已经安装了swiper slider(react版本)并创建了一个自定义块。当我在后端添加块时,它工作得很顺利,我可以很好地滑动。但当我在前端保存和查看时,什么都不会出现。在后端刷新后检查错误消息时,我看到以下消息:

未捕获错误:钩子调用无效。钩子只能在函数组件的主体内部调用。发生这种情况的原因如下:

您可能有不匹配的React版本和渲染器(如React DOM)

  • 您可能违反了挂钩规则,您可能在同一个应用程序中有多个React副本
    import { registerBlockType } from "@wordpress/blocks";
    import { useBlockProps } from "@wordpress/block-editor";
    import { Swiper, SwiperSlide } from "swiper/react";
    import "swiper/css";
    
    import "./editor.scss";
    import "./style.scss";
    
    import json from "./block.json";
    import { __ } from "@wordpress/i18n";
    const { name, ...settings } = json;
    
    registerBlockType(name, {
        ...settings,
        edit: (props) => {
            return (
                <div {...useBlockProps()}>
                    <Swiper
                        spaceBetween={50}
                        slidesPerView={3}
                        onSlideChange={() => console.log("slide change")}
                        onSwiper={(swiper) => console.log(swiper)}
                    >
                        <SwiperSlide>Slide 1</SwiperSlide>
                        <SwiperSlide>Slide 2</SwiperSlide>
                        <SwiperSlide>Slide 3</SwiperSlide>
                        <SwiperSlide>Slide 4</SwiperSlide>
                    </Swiper>
                </div>
            );
        },
        save: () => {
            return (
                <div {...useBlockProps.save()}>
                    <Swiper spaceBetween={50} slidesPerView={3}>
                        <SwiperSlide>Slide 1</SwiperSlide>
                        <SwiperSlide>Slide 2</SwiperSlide>
                        <SwiperSlide>Slide 3</SwiperSlide>
                        <SwiperSlide>Slide 4</SwiperSlide>
                    </Swiper>
                </div>
            );
        },
    });
    

  • 1 个回复
    最合适的回答,由SO网友:Tom J Nowell 整理而成

    您误解了save组件的用途。save组件的目标不是返回交互式React组件,而是返回一些可以转换为静态HTML并以字符串形式保存在数据库中的内容。

    因为只有HTML被保存,所以您的责任是在前端加载javascript,找到该HTML并将其转换为Swiper滑块。

    因此,您不应尝试在保存组件中直接或间接通过库执行以下任何操作:

    事件侦听器(event listeners)的反应状态(react state)回调/效果/HTTP请求等甚至可以在未发生保存时运行保存组件,例如通过将保存的块与保存组件进行比较来验证块时。

    因此,考虑到这一点,使用<Swiper><SwiperSlide> 此处为组件。

    相反,请遵循Swiper文档并生成实际的HTML:

    <!-- Slider main container -->
    <div class="swiper">
      <!-- Additional required wrapper -->
      <div class="swiper-wrapper">
        <!-- Slides -->
        <div class="swiper-slide">Slide 1</div>
        <div class="swiper-slide">Slide 2</div>
        <div class="swiper-slide">Slide 3</div>
        ...
      </div>
      <!-- If we need pagination -->
      <div class="swiper-pagination"></div>
    
      <!-- If we need navigation buttons -->
      <div class="swiper-button-prev"></div>
      <div class="swiper-button-next"></div>
    
      <!-- If we need scrollbar -->
      <div class="swiper-scrollbar"></div>
    </div>
    

    https://swiperjs.com/get-started#add-swiper-html-layout

    针对JSX进行调整并以这种方式保存。

    另一方面,Swiper库检测幻灯片的方式<Swiper> 组件是通过检查虚拟dom并查找类型<SwiperSlide>. 这意味着如果使用滑块,则无法找到幻灯片。这意味着在古腾堡不可能有用户可配置的幻灯片,因为用于提供块信息的高阶组件。这种方式不可能有嵌套块。Swiper会将子块解释为附加在滑块之后的附加HTML,即使它们是幻灯片或<SwiperSlide> 组件。

    相关推荐