Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

swiper/react onSlideChange's callback wouldn't be updated #3762

Closed
1 of 3 tasks
ddhp opened this issue Aug 11, 2020 · 6 comments
Closed
1 of 3 tasks

swiper/react onSlideChange's callback wouldn't be updated #3762

ddhp opened this issue Aug 11, 2020 · 6 comments
Labels

Comments

@ddhp
Copy link

ddhp commented Aug 11, 2020

This is a (multiple allowed):

What you did

A callback in my react component is set to swiper/react component, and I want to update that function

Expected Behavior

callback function would be updated

Actual Behavior

please refer to the provided codesandbox link, reproducing steps:

  • click the random button, the list is updated
  • change active slide with navigation, the List in onSlideChange Cb wouldn't be updated because list in the callback stays the same

I am not sure if this is related to how event listeners are updated to the swiper instance from react component. I quickly checked the source code but I can't find any clue. I think it might be much easier to look for help here so if someone can give me some hint that would be really appreciated!

@ddhp
Copy link
Author

ddhp commented Aug 12, 2020

I workaround by adding event listeners to swiper instance in useEffect hook, ie.

const Component = () => {
  const [swiperInstance, setSwiperInstance] = useState(null);

  const onSlideChange = useCallback(() => {
    setListInCb(list);
  }, [list]);

  useEffect(() => {
    if (swiperInstance) {
      swiperInstance.on("slideChange", onSlideChange);
    }
  }, [swiperInstance, onSlideChange]);

  return (
    <Swiper navigation>
      {items}
    </Swiper>
  );
}

@kmvan
Copy link

kmvan commented Oct 22, 2020

File: App_fixed.jsx

const onRandomClick = useCallback(() => {
    setList([
      {
        id: Math.floor(10 * Math.random())
      },
      {
        id: Math.floor(10 * Math.random())
      },
      {
        id: Math.floor(10 * Math.random())
      }
    ]);
  }, []);

I added new item, but swper items are not update after clicked.

@kmvan
Copy link

kmvan commented Oct 22, 2020

May need to call swiper.updateSlides()

@JaosnHsieh
Copy link

JaosnHsieh commented Nov 17, 2020

useRef as another workaround to get latest state value in the component when onSlideChange not get updated.

import React, { useState, useCallback, useRef } from "react";
import SwiperCore, { Navigation } from "swiper";
import { Swiper, SwiperSlide } from "swiper/react";
import "./styles.css";

SwiperCore.use([Navigation]);

export default function App() {
  const listRef = useRef(null);
  const [list, setList] = useState([
    {
      id: "1"
    },
    {
      id: "2"
    }
  ]);
  const setListAndRef = (l) => {
    setList(l);
    listRef.current = l;
  };
  const [listInCb, setListInCb] = useState(list);

  const onSlideChange = useCallback(() => {
    // list stays the same as the intial value
    console.log(JSON.stringify(listRef.current));
    setListInCb(listRef.current);
  }, []);

  const onRandomClick = useCallback(() => {
    setListAndRef([
      {
        id: Math.floor(1000 * Math.random())
      },
      {
        id: Math.floor(1000 * Math.random())
      }
    ]);
  }, []);

  const items = list.map((li) => (
    <SwiperSlide key={li.id}>{li.id}</SwiperSlide>
  ));
  return (
    <div className="App">
      <Swiper navigation onSlideChange={onSlideChange}>
        {items}
      </Swiper>
      <button type="button" onClick={onRandomClick}>
        Random list
      </button>
      <p>List in onSlideChange Cb</p>
      {JSON.stringify(listInCb)}
    </div>
  );
}

based on your example

https://codesandbox.io/s/swiper-event-listener-forked-pe3ex?file=/src/App.js:0-1295

@dreamofdark
Copy link

also same with onClick callback
can it be fixed?

@vltansky vltansky added the React label Jan 21, 2021
@saveman71
Copy link

From what I can gather, https://github.com/nolimits4web/swiper/blob/f8ca5c094b7fa5d361b80510340256ecbfca75f9/src/react/get-changed-params.js should properly notice that the event handler changed.

Then https://github.com/nolimits4web/swiper/blob/f8ca5c094b7fa5d361b80510340256ecbfca75f9/src/react/update-swiper.js doesn't do anything with that info.

It would need to .off and .on the changed event handlers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants