【问题标题】:Swiper React | How to create custom navigation/pagination components using React refs?刷卡反应 |如何使用 React refs 创建自定义导航/分页组件?
【发布时间】:2020-09-28 09:23:23
【问题描述】:

SwiperJS documentation 声明导航 prevEl/nextEl 可以是“string”或“HTMLElement”类型。使用字符串选择器很简单:

const MySwiper = (props) => (
  <Swiper
    navigation={{
      prevEl: '.prev',
      nextEl: '.next',
    }}
    {...props}
  >
    <SwiperSlide>slide 1</SwiperSlide>
    <SwiperSlide>slide 2</SwiperSlide>
    <div className="prev" />
    <div className="next" />
  </Swiper>
)

但是,如何使用 React refs 正确实现这一点?使用 HTML 节点而不是字符串选择器允许将导航 prevEl/nextEl 范围限定为 MySwiper 的每个渲染实例。

const App = () => (
  <div>
    <MySwiper className="mySwiper1" />
    <MySwiper className="mySwiper2" />
  </div>
)

在上面的 App 示例中,.mySwiper2 的导航 prevEl/nextEl 应该触发 .mySwiper1 的滑动,字符串选择器会发生这种情况。

我目前的悲伤和 hacky 解决方法:

const MySwiper = () => {
  const navigationPrevRef = React.useRef(null)
  const navigationNextRef = React.useRef(null)

  return (
    <Swiper
      navigation={{
        // Both prevEl & nextEl are null at render so this does not work
        prevEl: navigationPrevRef.current,
        nextEl: navigationNextRef.current,
      }}
      onSwiper={(swiper) => {
        // Delay execution for the refs to be defined
        setTimeout(() => {
          // Override prevEl & nextEl now that refs are defined
          swiper.params.navigation.prevEl = navigationPrevRef.current
          swiper.params.navigation.nextEl = navigationNextRef.current

          // Re-init navigation
          swiper.navigation.destroy()
          swiper.navigation.init()
          swiper.navigation.update()
        })
      }}
    >
      <SwiperSlide>slide 1</SwiperSlide>
      <SwiperSlide>slide 2</SwiperSlide>
      <div ref={navigationPrevRef} />
      <div ref={navigationNextRef} />
    </Swiper>
  )
}

【问题讨论】:

    标签: reactjs swiper


    【解决方案1】:

    我想我解决了这个问题,我也遇到了同样的问题,但最后,让我们开始吧

     1. import SwiperCore, { Navigation} from 'swiper'
     2. SwiperCore.use([Navigation])
     3. i will use your exmaple:     
    
        const MySwiper = () => {
          const navigationPrevRef = React.useRef(null)
          const navigationNextRef = React.useRef(null)
          return (
            <Swiper
              navigation={{
                prevEl: navigationPrevRef.current,
                nextEl: navigationNextRef.current,
              }}
             onBeforeInit={{
                  swiper.params.navigation.prevEl = navigationPrevRef.current;
                  swiper.params.navigation.nextEl = navigationNextRef.current;
             }}
            >
              <SwiperSlide>slide 1</SwiperSlide>
              <SwiperSlide>slide 2</SwiperSlide>
              <div ref={navigationPrevRef} />
              <div ref={navigationNextRef} />
            </Swiper>
          )
        }
    

    就是这样,所以如果您检查 Swiper duc,则有一个仅用于 API 的页面,您可以在其中找到一个讨论 swiper 提供的事件的部分,无论如何我希望这会有所帮助

    【讨论】:

    • 问题是关于分页和导航的问题!
    【解决方案2】:

    注意将 onBeforeInit 插入 Amine D 样本的小错误。

    更正的代码:

    const MySwiper = () => {
      const navigationPrevRef = React.useRef(null)
      const navigationNextRef = React.useRef(null)
      return (
        <Swiper
          navigation={{
            prevEl: navigationPrevRef.current,
            nextEl: navigationNextRef.current,
          }}
         onBeforeInit={(swiper) => {
              swiper.params.navigation.prevEl = navigationPrevRef.current;
              swiper.params.navigation.nextEl = navigationNextRef.current;
         }}
        >
          <SwiperSlide>slide 1</SwiperSlide>
          <SwiperSlide>slide 2</SwiperSlide>
          <div ref={navigationPrevRef} />
          <div ref={navigationNextRef} />
        </Swiper>
      )
    }
    

    【讨论】:

      【解决方案3】:

      在 Swiper v6.2.0 中直接传递 refs 显然是不可能的。

      我还为图书馆作者回答的任何人创建了一个 Github 问题。 https://github.com/nolimits4web/swiper/issues/3855

      【讨论】:

        【解决方案4】:

        根据前面的答案,下面是完整的代码。这可能会帮助您根据需要实施。

        import React from "react";
        import SwiperCore, { Navigation } from 'swiper';
        import { Swiper, SwiperSlide } from "swiper/react";
        
        SwiperCore.use([Navigation]);
        
        const MySwiper = () => {
              const navigationPrevRef = React.useRef(null)
              const navigationNextRef = React.useRef(null)
              return (
                <Swiper
                  navigation={{
                    prevEl: navigationPrevRef.current,
                    nextEl: navigationNextRef.current,
                  }}
                 setTimeout(() => {
                  // Override prevEl & nextEl now that refs are defined
                  swiper.params.navigation.prevEl = navigationPrevRef.current
                  swiper.params.navigation.nextEl = navigationNextRef.current
        
                  // Re-init navigation
                  swiper.navigation.destroy()
                  swiper.navigation.init()
                  swiper.navigation.update()
                })
                >
                  <SwiperSlide>slide 1</SwiperSlide>
                  <SwiperSlide>slide 2</SwiperSlide>
                  <div ref={navigationPrevRef} />
                  <div ref={navigationNextRef} />
                </Swiper>
              )
            }
        
        const App = () => (
          <div>
            <MySwiper className="mySwiper1" />
            <MySwiper className="mySwiper2" />
          </div>
        )
        
        ReactDOM.render(<App/>, document.getElementById('root'));
        

        【讨论】:

          【解决方案5】:

          虽然 Pierrat's answer 最初确实为我解决了这个问题,但我遇到了一个错误,即导航按钮在我暂停并重新启动 Swiper 之后才会执行任何操作。

          为了解决这个问题,我创建了自己的函数来处理更新并改用这些函数。

          const MyComponent = () => {
            const sliderRef = useRef(null);
          
            const handlePrev = useCallback(() => {
              if (!sliderRef.current) return;
              sliderRef.current.swiper.slidePrev();
            }, []);
          
            const handleNext = useCallback(() => {
              if (!sliderRef.current) return;
              sliderRef.current.swiper.slideNext();
            }, []);
          
            return (
              <div>
                <Swiper ref={sliderRef}>
                  <SwiperSlide />
                  ...slides
                  <SwiperSlide />
                </Swiper>
                <div className="prev-arrow" onClick={handlePrev} />
                <div className="next-arrow" onClick={handleNext} />
              </div>
            )
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-07-31
            • 2020-04-05
            • 1970-01-01
            相关资源
            最近更新 更多